因为0.1版本整体代码大概只有350行,比较简单。所以本篇文章会以Flask 0.1版本源码为基础进行剖析Flask应用的启动过程。

Flask参考资料flask,官网有一个最简单app:

from flask import Flask
app = Flask(__name__) @app.route('/hello')
def hello_world():
return 'Hello World!' if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080,debug=True)

  

下面就以上面这个最简单的Flask app为起点,以v0.1版本源码为核心进行说明整个Flask应用的启动过程:

一、初始化App

from flask import Flask    #导入Flask类
app = Flask(__name__) #1、实例化Flask app

  

flask.py文件:

1.1、定义类变量

class Flask(object):

'''
全局变量
'''
request_class = Request
response_class = Response
static_path = '/static'
secret_key = None
session_cookie_name = 'session'
jinja_options = dict(
autoescape=True,
extensions=['jinja2.ext.autoescape', 'jinja2.ext.with_']
)

  

a、request_class变量是一个Request类,Request类继承自werkzeug的Request类。它调用了werkzeug的Request类的构造函数,RequestBase.__init__(self, environ)。然后又初始化了endpoint和view_args两个变量。

b、response_class变量是一个Response类。继承自werkzeug的Reponse类。且自己初始化了变量default_mimetype=‘text/html’。

c、static_path是静态文件路径,默认值为/static。

d、secret_key默认值为None。关于secret_key的作用,用官方的语言来解释:

If a secret key is set, cryptographic components can use this to sign cookies and other things. Set this to a complex random value when you want to use the secure cookie for instance.
如果设置了secret_key,加密组件使用这个key签名cookies。当你要使用安全cookie,你要把这个key设置成复杂的随机值。 This attribute can also be configured from the config with the SECRET_KEY configuration key. Defaults to None.
这个属性可以通过在配置文件中设置SECRET_KEY来设置。默值为None。

  

e、session_cookie_name,session的名字为session。

f、jinja_options选项初始化。

1.2、初始化构造函数

def __init__(self, package_name):
self.debug = False #debug变量为False
self.package_name = package_name #一般为__name__,如果以本模块运行,则为__main__;如果是被调用,则为app文件名。
self.root_path = _get_package_path(self.package_name) #获取app的绝对路径
self.view_functions = {} #视图函数
self.error_handlers = {} #错误处理
self.before_request_funcs = [] #HTTP请求之前需要执行的函数
self.after_request_funcs = [] #HTTP请求结束之后,需要执行的函数
self.template_context_processors = [_default_template_ctx_processor] #上下文模板变量:session、g、request self.url_map = Map() #url集合
if self.static_path is not None: #self.static_path默认值为'/static',所以默认会把它加入到url_map集合中。Map([<Rule '/static/<filename>' -> static>])
self.url_map.add(Rule(self.static_path + '/<filename>',
build_only=True, endpoint='static'))
if pkg_resources is not None:
target = (self.package_name, 'static')
else:
target = os.path.join(self.root_path, 'static')
self.wsgi_app = SharedDataMiddleware(self.wsgi_app, {
self.static_path: target
})
self.jinja_env = Environment(loader=self.create_jinja_loader(),
**self.jinja_options)
self.jinja_env.globals.update(
url_for=url_for,
get_flashed_messages=get_flashed_messages
)

  

在构造函数中,主要定义了一些变量(debug、包名、包路径、视图函数、上下文相关、路由、static路径、模板相关环境)

二、路由处理

@app.route('/hello')
def hello_world():
return 'Hello World!'

  

flask.py文件

2.1 定义路由装饰器

功能就是完成url_map和view_functions的初始化,其中Rule是werkzeug提供的工具。

def route(self, rule, **options):   #route装饰器,装饰路由的同时,把路由添加进Map,添加视图函数,确保路由和视图函数映射起来
def decorator(f):
self.add_url_rule(rule, f.__name__, **options) #Map([<Rule '/hello'(HEAD,GET) -> hello_world>])
self.view_functions[f.__name__] = f #view_functions = {'hello_world':hello_world}
return f
return decorator
def add_url_rule(self, rule, endpoint, **options): options['endpoint'] = endpoint
options.setdefault('methods', ('GET',))
self.url_map.add(Rule(rule, **options))

  

三、app.run()

前面两个步骤,都是初始化操作,为后续启动做准备。包括初始化环境变量和路由添加。

if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080,debug=True)

  

app正式启动了。过程如下:

flask.run()
--> werkzeug.run_simple()
    --> werkzeug.inner()
       --> werkzeug.serving.make_server()
         -->serve_forever()
           -->SocketServer.BaseServer.HTTPServer.serve_forever() #While True:****

  

至此,一个flask的app已经跑起来了。

Flask学习-Flask app启动过程的更多相关文章

  1. wxWidgets源码分析(1) - App启动过程

    目录 APP启动过程 wxApp入口定义 wxApp实例化准备 wxApp的实例化 wxApp运行 总结 APP启动过程 本文主要介绍wxWidgets应用程序的启动过程,从app.cpp入手. wx ...

  2. Flask学习-Flask app接受第一个HTTP请求

    一.__call__() 在Flask app启动后,一旦uwsgi收到来自web server的请求,就会调用后端app,其实此时就是调用app的__call__(environ,start_res ...

  3. Flask学习-Flask基础之WSGI

    一.WSGI为什么会出现? 在学习一个东西之前,我们肯定想知道:它为什么会出现?那么,WSGI为什么会出现呢? 我们知道,部署一个web应用,经常需要使用nginx.apache或者IIS等web服务 ...

  4. [Flask]学习Flask第三天笔记总结

    from flask import Flask,render_template,request from others import checkLogin app = Flask(__name__) ...

  5. tiny4412学习之u-boot启动过程

    这个文档简要分析了tiny4412自带的u-boot的启动过程,这个u-boot启用了mmu,并且命令的接收和执行方式跟以前的不同. 文档下载地址: http://pan.baidu.com/s/1s ...

  6. Oracle学习笔记--Oracle启动过程归纳整理

    Oracle 启动过程分为nomount状态mount状态open状态 每个状态下Oracle都会进行不同的操作:1.nomount状态 在$ORACLE_HOME/dbs目录下寻找参数文件 参数文件 ...

  7. android app启动过程(转)

    Native进程的运行过程 一般程序的启动步骤,可以用下图描述.程序由内核加载分析,使用linker链接需要的共享库,然后从c运行库的入口开始执行. 通常,native进程是由shell或者init启 ...

  8. android app启动过程

    Native进程的运行过程 一般程序的启动步骤,可以用下图描述.程序由内核加载分析,使用linker链接需要的共享库,然后从c运行库的入口开始执行. 通常,native进程是由shell或者init启 ...

  9. 安卓 应用app启动过程

    韩梦飞沙 yue31313 韩亚飞 han_meng_fei_sha 313134555@qq.com 从用户点击 Launcher 上的 App 图标,到显示出 App 界面时主要发生的事情.知晓以 ...

随机推荐

  1. jmeter之数据库相关

    一.JDBC Connection Configuration 1.Variable Name Bound to Pool-Variable Name:连接池名称, JDBC Request通过此名称 ...

  2. shell 的echo和 printf

    shell的echo指令是输出语句  就好比Python的print 在显示字符串的时候可以省略双引号  但是最好还是带上 echo ' Ti is a dashaobing' echo Ti is ...

  3. python基础学习24----使用pymysql连接mysql

    使用pymysql连接mysql 安装pymysql pymysql安装可以通过两种方式 使用pip安装 首先简单说一下pip的使用方法 获取帮助 pip --help 升级 pip pip inst ...

  4. Sr Software Engineer - Big Data Team

    Sr Software Engineer - Big Data Team   About UberWe’re changing the way people think about transport ...

  5. unbuntu 安装python包提示E: Unable to locate package python-timeout

    今天本想着在unbuntu环境下安装python的一个包,安装了几次都提示 E: Unable to locate package python-timeout 查阅了一些信息才知道,原来是一些软件源 ...

  6. JAVA引用的种类

    最近在进行Java项目开发的时候,由于业务的原因,有时候new的对象会比较多,这个时候我总是有一个疑惑?那就是JVM在何时决定回收一个Java对象所占据的内存?这个问题其实对整个web系统来说是一个比 ...

  7. 分享-结合demo讲解JS引擎工作原理

    代码如下: var x = 1; function A(y){ var x = 2; function B(z){ console.log(x+y+z); } return B; } var C = ...

  8. CSS3的新增选择器

    一.兄弟选择器:选择E元素所有兄弟元素F. <style> p~p{ color:#f00;} </style> </head> <body> < ...

  9. VC++编译错误error C2065: “HANDLE”: 未声明的标识符及添加winbase.h后提示winbase.h(243): error C2146: 语法错误: 缺少“;”(在标识符“Internal”的前面)的解决办法

    问题描述: VC++程序编译时提示错误:error C2065: “HANDLE”: 未声明的标识符等众多错误提示,如下所示: error C2065: “HANDLE”: 未声明的标识符 error ...

  10. jmeter接口测试4-使用数据库mysql构造参数

    jmeter测试中,测试数据一般和测试用例分离 测试数据一般可以使用csv构造,进行参数化 但也可以使用mysql等数据库构造 方案一:一个线程循环调用mysql数据,不是并发,不适用于性能测试,更适 ...