flask中首先我们需要实例化一个Flask对象,而这个Flask对象进行了大量的封装。我们去掉一些不必要的内容,然后进行简单分析,随着分析的深入,后面会对前面内容进行更新,说明。
class Flask():
# 静态字段
request_class = Request
response_class = Response
config_class = Config
url_rule_class = Rule
url_map_class = Map
template_folder = None
def __init__(self,
static_url_path=None,
static_folder="static",
template_folder="templates",
):
self.static_url_path = static_url_path
self.static_folder = static_folder
self.view_functions = {}
self.before_request_funcs = {}
self.before_first_request_funcs = []
self.after_request_funcs = {}
self.blueprints = {}
self.url_map = self.url_map_class()
if self.has_static_folder:
self.add_url_rule(
self.static_url_path + "/<path:filename>",
endpoint="static",
host=static_host,
view_func=self.send_static_file,
)
从Django的经验来看,静态字段,分别为请求,响应,配置,路由,模板文件。
self.static_url_path = static_url_path指定静态文件的路由
self.static_folder = static_folder 则是静态文件的文件夹,下面有一个判断:
if self.has_static_folder:
self.add_url_rule(
self.static_url_path + "/<path:filename>",
endpoint="static",
host=static_host,
view_func=self.send_static_file,
)
has_static_folder方法判断是否指定了static_folder,如果没有返回False,否则返回True.
@property
def has_static_folder(self):
return self.static_folder is not None
如果指定了static_folder,那么意味着需要为静态文件指定Url(如果没有静态文件夹,当然也没必要指定url)
然后调用add_url_rule方法:这里去掉了一些方法
def add_url_rule(
self,
rule,
endpoint=None,
view_func=None,
provide_automatic_options=None,
**options
):
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)
options["endpoint"] = endpoint
methods = options.pop("methods", None)
# if the methods are not given and the view_func object knows its
# methods we can use that instead. If neither exists, we go with
# a tuple of only ``GET`` as default.
if methods is None:
methods = getattr(view_func, "methods", None) or ("GET",)
methods = set(item.upper() for item in methods)
# Methods that should always be added
required_methods = set(getattr(view_func, "required_methods", ()))
# Add the required methods now.
methods |= required_methods
rule = self.url_rule_class(rule, methods=methods, **options)
rule.provide_automatic_options = provide_automatic_options
self.url_map.add(rule)
if view_func is not None:
old_func = self.view_functions.get(endpoint)
if old_func is not None and old_func != view_func:
raise AssertionError(
"View function mapping is overwriting an "
"existing endpoint function: %s" % endpoint
)
self.view_functions[endpoint] = view_func
首先判断别名,如果没指定别名,别名被设定为函数名,然后将别名保存在options中。
接着是方法:先从Options中获取别名,如果没有,则得到None,即没有指定方法,那么methods被设置为GET,然后将方法名变成大写
再接着是rule, 即url, 通过url被 rule = self.url_rule_class(rule, methods=methods, **options)用来实例化一个url_rule_class=Rule对象,接着这个rule对象被 url_map=Map调用add方法封装成了Map对象。
最后去view_func中获取当前endpoint对应的视图函数,如果视图函数与当前函数名不同则报错,如果没有endpoint就添加当前endpoint与函数对应的关系到view_func字典中。
上面就是实例化Flask对象阶段所做的事情,简单总结一下:
指定很多静态属性,及其它属性。
指定静态文件的文件夹,并为它指定路由,在些过程中指定了请求方法,建立url与视图函数的对应关系。