python学习(七)-装饰器

代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
要自定义log的文本:

def log(text):
    def decorator(func):
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator

这个3层嵌套的decorator用法如下:

@log('execute')
def now():
    print('2015-3-25')

执行结果如下:

>>> now()
execute now():
2015-3-25

和两层嵌套的decorator相比,3层嵌套的效果是这样的:

>>> now = log('execute')(now)

我们来剖析上面的语句,首先执行log('execute'),返回的是decorator函数,再调用返回的函数,参数是now函数,返回值最终是wrapper函数。
函数也是对象,它有name等属性,但你去看经过decorator装饰之后的函数,它们的name已经从原来的'now'变成了'wrapper':

>>> now.__name__
'wrapper'

因为返回的那个wrapper()函数名字就是'wrapper',所以,需要把原始函数的name等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。

不需要编写wrapper.name = func.name这样的代码,Python内置的functools.wraps就是干这个事的,所以,一个完整的decorator的写法如下:

import functools

def log(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kw):
            print('%s %s():' % (text, func.__name__))
            return func(*args, **kw)
        return wrapper
    return decorator
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 要点: 函数式编程:注意不是“函数编程”,多了一个“式” 模块:如何使用模块 面向对象编程:面向对象的概念、属性、...
    victorsungo阅读 1,601评论 0 6
  • 本篇将介绍Python的装饰器用法,更都内容请参考: Python学习指南 装饰器 由于函数也是一个对象,而且函数...
    小七奇奇阅读 281评论 0 0
  • 第五项修炼 学习力 1有自我超越的动力 2改变自己的心智模式 3共同愿景 4团队学习 互相启发 5系统思考 思考问...
    宫晓杰阅读 129评论 0 0
  • 希望这夕阳的余晖,等等我。 愿这悠长岁月温柔安好 有回忆煮酒 愿你没有软肋也不需要铠甲
    li诗里阅读 162评论 0 0
  • 月儿,入冬以前的最后一场中雨 冰冷的敲打深秋的屋顶 叩问大地坚硬的沉默,我了解的沉默 大彻大悟之后的秋末,安静。 ...
    杨昊田阅读 906评论 22 28