python flask route中装饰器的使用

两盒软妹~` 提交于 2019-12-10 04:47:38

问题:route中的装饰器为什么感觉和平时使用的不太一样,装饰器带参数和不太参数有什么区别?被修饰的函数带参数和不带参数有什么区别?

测试1:装饰器不带参数,被修饰的函数也不带参数。

def log(func):
    print"execute log"
    print func
    def use_log():
        print "execute use log"
        def wrapper():
            print "start"
            func()
            print "end"
            return
        return wrapper
    return use_log
 
@log
def cal():
    print "1+2"

此时输出为:

execute log
<function cal at 0x7fa64535f668> #这里的function为cal的函数地址

如果执行cal()那么将会使用use_log函数,返回的是wrapper()

execute log
<function cal at 0x7f42ee7a4668>
execute use log

如果执行cal()的返回值,那么将执行cal()函数体的内容

result = cal()
result()

结果为:

execute log
<function cal at 0x7f38dc4d1668>
execute use log
start
1+2
end

测试2:如果装饰器带参数,被修饰的函数不带参数

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def log(func): #这里的func为装饰器函数参数
    print"execute log"
    print func #这里的func为装饰器函数参数
    def use_log(func): #这里的func为函数cal()的地址
        print "execute use log"
        print func #这里的func为函数cal()的地址
        def wrapper():
            print "start"
            func()
            print "end"
            return
        return wrapper
    return use_log
 
@log('log')
def cal():
    print "1+2"
 
#这个时候数输出结果为:
execute log
log
execute use log
<function cal at 0x7f0c666b46e0>

这个时候调用cal()那么将会执行wrapper()的函数体+cal()的函数体。

测试3:如果装饰器不带参数,被修饰的函数带参数

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def log(func): #func 为cal()函数的地址
    print"execute log"
    def use_log(param): #param为cal的参数param
        print "execute use log"
        print param
        def wrapper():
            print "start"
            func(param) #func 为cal()函数的地址,param为cal的参数param
            print "end"
            return
        return wrapper
    return use_log
 
@log
def cal(param):
    print "1+2"
 
result = cal('cal')
result()
 
#执行的结果为:
execute log
execute use log
cal
start
1+2
end
#如果注掉最后两行代码,那么只有输出
execute log

测试4:如果装饰器带参数,被修饰的函数也带参数。最复杂的情况。

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def log(func): #func为装饰器的参数
    print"execute log"
    def use_log(func): #func为cal的函数地址
        print "execute use log"
        print func #func为cal的函数地址
        def wrapper(param): #param为cal的参数
            print "start"
            func(param)
            print "end"
            return
        return wrapper
    return use_log
 
@log('test')
def cal(param):
    print "1+2"
 
result = cal('cal')
 
#执行的结果为:
execute log
execute use log
<function cal at 0x7f23bbc6d6e0>
start
1+2
end

经过上面的分析之后,再看flask中使用的是哪种情况:

样例代码:

from flask import Flask
 
app = Flask(__name__)
 
@app.route('/')
def hello():
    print 'execute hello function'
    return 'Hello, World!'

@app.route(’/’)的代码如下:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:579817333 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
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):
        endpoint = options.pop('endpoint', None)
        self.add_url_rule(rule, endpoint, f, **options)
        print "this param has been accessed"
        return f
return decorator

可以看到装饰器的参数为‘/’,被修饰的函数为:hello(),所以这里属于第二种情况,即使不调用hello()函数,decorator的函数体也是被执行的,也就是说,只要使用装饰器添加了路由规则,那么就会被加入到map中形成映射关系。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!