zoukankan      html  css  js  c++  java
  • python中装饰器的执行细节

    本文代码借用 廖雪峰的python教程(官网:http://www.liaoxuefeng.com/)

    不了解装饰器的可以先看教程

    直接上带参数装饰器的代码

    def log(text):
        def decorator(func):
            def wrapper(*args, **kw):
                print '%s %s():' % (text, func.__name__)
                return func(*args, **kw)
            return wrapper
        return decorator
    
    @log('execute')
    def now():
        print '2013-12-25'
    
    now()
    
    控制台输出:
    execute now():
    2013-12-25

    这都很好理解,但是我在看到教程中的用flask框架写WEB应用时

    @app.route('/', methods=['GET', 'POST'])
    def home():
        return '<h1>Home</h1>'

    只要在函数前面添加这样的装饰器,就能达到自动地把URL和函数给关联起来的目的

    可是为什么这样写装饰器就能有这样的效果呢

    我们来看了一下这个app.route这个装饰器的源码

        def route(self, rule, **options):
            def decorator(f):
                endpoint = options.pop('endpoint', None)
                self.add_url_rule(rule, endpoint, f, **options)
                return f
            return decorator

    体现这个功能的肯定是在return f前面的两行代码,它把这个映射规则添加带app对象中,细节我们不用理会

    可是,这些映射规则不是应该在我们调用home函数前就应该建立起来吗?不然怎么自动映射到home这个函数。

    会造成这样的困惑的原因是我一直误解的装饰器的装饰过程,其实装饰器的装饰过程是在函数定义的时候就执行了,即你在调用home之前,home早就装饰器碉堡换成装饰器返回的函数了。也就是说,就算你没调用home函数,装饰器的代码也早就执行了。

    我们用代码来验证一下:

    def log(text):
        print 'print 1'
        def decorator(func):
            print 'print 2'
            def wrapper(*args, **kw):
                print '%s %s():' % (text, func.__name__)
                return func(*args, **kw)
            return wrapper
        return decorator
    
    @log('NiHao')
    def now():
        print '2013-12-25'
    
    控制台输出:
    print 1
    print 2

    结果显示:我们还没调用now(),两个print语句已经执行了。

    得证。

  • 相关阅读:
    推荐一本书 改善你的视力:跟眼镜说再见
    Gentoo中gcc4.1.2到gcc4.3.2的升级
    msbuild学习的一些相关链接
    SqlServer 2005安装问题
    Gentoo linux中安装php5运行环境
    sql 时间函数(全)
    asp.net中的对话框
    win7 资源管理器指向我的电脑
    C/C++ 位操作 总结
    【转】Java字节序转换
  • 原文地址:https://www.cnblogs.com/xiaominghupan/p/4250110.html
Copyright © 2011-2022 走看看