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语句已经执行了。

    得证。

  • 相关阅读:
    docker基本指令
    Process API
    Go的Context用法
    golang的可空类型和零值
    动态编程(DynamicObject、ExpandoObject)
    git clean
    SQL Server Join
    公用表表达式 Common Table Expression
    ubuntu安装mysql
    asp.net core-使用Nlog和log4net
  • 原文地址:https://www.cnblogs.com/xiaominghupan/p/4250110.html
Copyright © 2011-2022 走看看