#从flask这个包中导入Flask这个类 #Flask这个类是项目的核心,以后很多操作都是基于这个类的对象 #注册url、注册蓝图等都是基于这个类的对象 from flask import Flask #创建一个Flask对象,传递__name__参数进去 #__name__参数的作用: #1.可以规定模板和静态文件的查找路劲 #2.以后一些Flask插件,比如Flask-migrate、Flask-SQLAlchemy如果报错了, #那么Flask可以通过这个参数找到具体的报错位置 app = Flask(__name__) #@app.route:是一个装饰器 #@app。route(“/”)就是将url中的/映射到hello_world这个视图函数上面 #以后你访问我这个网站的/目录的时候,会执行hello_world这个函数,然后将这个 #返回值返回给浏览器 @app.route('/') def hello_world(): return 'Hello World' if __name__ == '__main__': #app.run():Flask中的一个测试应用服务 # while True: run相当于 # listen() # input() app.run()
看下 route(‘/’)的源码
先看下一般我们使用装饰器怎么用
无参装饰器
User = None def decorater(func): def wapper(*args,**kwargs): if User: return func(*args,**kwargs) else: #就执行相应逻辑 pass return wapper
有参装饰器
def func(fun,*args,**kwargs): def decorater(f): def wapper(*args, **kwargs): if User: return func(*args, **kwargs) else: # 就执行相应逻辑 pass return wapper return decorater
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————-_
下面看下flask里面是怎么处理的
def route(self, rule, **options):
"""A decorator that is used to register a view function for a
given URL rule. This does the same thing as :meth:`add_url_rule`
but is intended for decorator usage::
@app.route('/')
def index():
return 'Hello World'
For more information refer to :ref:`url-route-registrations`.
:param rule: the URL rule as string
:param endpoint: the endpoint for the registered URL rule. Flask
itself assumes the name of the view function as
endpoint
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object. A change
to Werkzeug is handling of method options. methods
is a list of methods this rule should be limited
to (``GET``, ``POST`` etc.). By default a rule
just listens for ``GET`` (and implicitly ``HEAD``).
Starting with Flask 0.6, ``OPTIONS`` is implicitly
added and handled by the standard request handling.
"""
def decorator(f): #f就是那个注册函数但是这里没有执行
endpoint = options.pop('endpoint', None)
self.add_url_rule(rule, endpoint, f, **options) #而是将注册url传入进了 add_url_rule()这个函数,路由规则和注册函数进行绑定
return f
return decorator
————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
看下 add_url_rule
@setupmethod
def add_url_rule(self, rule, endpoint=None, view_func=None,
provide_automatic_options=None, **options):
"""Connects a URL rule. Works exactly like the :meth:`route`
decorator. If a view_func is provided it will be registered with the
endpoint.
Basically this example::
@app.route('/')
def index():
pass
Is equivalent to the following::
def index():
pass
app.add_url_rule('/', 'index', index)
If the view_func is not provided you will need to connect the endpoint
to a view function like so::
app.view_functions['index'] = index
Internally :meth:`route` invokes :meth:`add_url_rule` so if you want
to customize the behavior via subclassing you only need to change
this method.
For more information refer to :ref:`url-route-registrations`.
.. versionchanged:: 0.2
`view_func` parameter added.
.. versionchanged:: 0.6
``OPTIONS`` is added automatically as method.
:param rule: the URL rule as string
:param endpoint: the endpoint for the registered URL rule. Flask
itself assumes the name of the view function as
endpoint
:param view_func: the function to call when serving a request to the
provided endpoint
:param provide_automatic_options: controls whether the ``OPTIONS``
method should be added automatically. This can also be controlled
by setting the ``view_func.provide_automatic_options = False``
before adding the rule.
:param options: the options to be forwarded to the underlying
:class:`~werkzeug.routing.Rule` object. A change
to Werkzeug is handling of method options. methods
is a list of methods this rule should be limited
to (``GET``, ``POST`` etc.). By default a rule
just listens for ``GET`` (and implicitly ``HEAD``).
Starting with Flask 0.6, ``OPTIONS`` is implicitly
added and handled by the standard request handling.
"""
if endpoint is None:
endpoint = _endpoint_from_view_func(view_func)#这个是注册函数的名字
options['endpoint'] = endpoint #将字典的形式 将函数名字 绑定到 options这个字典上 键值对:
methods = options.pop('methods', None) #这里用了字典的pop方法,pop()这个方法有三个参数一个是self就是字典zij,
第二参数就是关键字,第三个就是没有找到这个关键字的默认参数
# 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.
如果没有给出方法,并且view_func对象知道它的方法
方法,我们可以用它来代替。如果两者都不存在,我们就一起去
只有' GET '作为defaul的元组
if methods is None:
methods = getattr(view_func, 'methods', None) or ('GET',)#这个用自省中动态的获取里面的方法,methods有值就是直接获取,没有就是None,None就不执行,执行
后面的默认参数元祖
if isinstance(methods, string_types):#这里methods是(‘GET’,)
raise TypeError('Allowed methods have to be iterables of strings, '
'for example: @app.route(..., methods=["POST"])')
methods = set(item.upper() for item in methods)
# Methods that should always be added
required_methods = set(getattr(view_func, 'required_methods', ()))
# starting with Flask 0.8 the view_func object can disable and
# force-enable the automatic options handling.
if provide_automatic_options is None:
provide_automatic_options = getattr(view_func,
'provide_automatic_options', None)
if provide_automatic_options is None:
if 'OPTIONS' not in methods:
provide_automatic_options = True
required_methods.add('OPTIONS')
else:
provide_automatic_options = False
# 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