zoukankan      html  css  js  c++  java
  • python flask route中装饰器的使用

    问题: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:如果装饰器带参数,被修饰的函数不带参数

    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:如果装饰器不带参数,被修饰的函数带参数

    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:如果装饰器带参数,被修饰的函数也带参数。最复杂的情况。

    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('/')的代码如下:

        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中形成映射关系。

  • 相关阅读:
    前端程序员容易忽视的一些基础知识
    一道前端学习题
    Unity调用Windows对话框保存时另存为弹框
    Unity镜子效果的实现(无需镜子Shader)
    Unity射线检测的用法总结
    unity中实现简单对象池,附教程原理
    Unity调用Window提示框Yes/No(英文提示窗)
    Unity调用Windows弹框、提示框(确认与否,中文)
    C#LinQ语法
    服务器的购买与网站的创建
  • 原文地址:https://www.cnblogs.com/Spider-spiders/p/10337798.html
Copyright © 2011-2022 走看看