Flask学习-Flask app启动过程
作者:@skyflask
转载本文请注明出处:https://www.cnblogs.com/skyflask/p/9194191.html
目录
一、初始化App
1.1、定义类变量
1.2、初始化构造函数
二、路由处理
2.1 定义路由装饰器
三、app.run()
因为0.1版本整体代码大概只有350行,比较简单。所以本篇文章会以Flask 0.1版本源码为基础进行剖析Flask应用的启动过程。
Flask参考资料flask,官网有一个最简单app:
1 2 3 4 5 6 7 8 9 | 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
1 2 | from flask import Flask #导入Flask类 app = Flask(__name__) #1、实例化Flask app |
flask.py文件:
1.1、定义类变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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的作用,用官方的语言来解释:
1 2 3 4 5 | 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、初始化构造函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | 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集合<br> 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路径、模板相关环境)
二、路由处理
1 2 3 | @app .route( '/hello' ) def hello_world(): return 'Hello World!' |
flask.py文件
2.1 定义路由装饰器
功能就是完成url_map和view_functions的初始化,其中Rule是werkzeug提供的工具。
1 2 3 4 5 6 7 8 9 10 11 | 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<br> def add_url_rule( self , rule, endpoint, * * options): options[ 'endpoint' ] = endpoint options.setdefault( 'methods' , ( 'GET' ,)) self .url_map.add(Rule(rule, * * options)) |
三、app.run()
前面两个步骤,都是初始化操作,为后续启动做准备。包括初始化环境变量和路由添加。
1 2 | if __name__ = = '__main__' : app.run(host = '0.0.0.0' , port = 8080 ,debug = True ) |
app正式启动了。过程如下:
1 2 3 4 5 6 | flask.run() --> werkzeug.run_simple() --> werkzeug.inner() --> werkzeug.serving.make_server() -->serve_forever() -->SocketServer.BaseServer.HTTPServer.serve_forever() #While True:**** |
至此,一个flask的app已经跑起来了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!