为了账号安全,请及时绑定邮箱和手机立即绑定

python 函数装饰器(Function Decorators)

标签:
Python

函数装饰器(Function Decorators)

python中函数装饰器的使用和Java中注解类似, 直接在函数定义的前一行加上装饰器即可. python除了函数装饰器还有类的装饰器.

使用及原理

@decodef target():
    pass

这样target函数就被deco装饰了, 其中deco是一个接收一个函数为参数的函数.

decorators只是一种语法糖, 和以下代码是等价的

def target():
    passtarget = deco(target)

两段代码的结果是一样的, target指向的由deco返回的函数, 而不一定指向原来定义的target函数.

总结一下: 装饰器是一个接收一个函数作为参数(可能还有其他的参数)的函数, 它的返回值也是一个函数.

另外一个重要的是装饰器的函数在运行时马上被执行, 这个应该比较好理解. 也就是说当你运行时被装饰函数马上执行. 可以看看下面这个例子

def dec(func):
    print('the decorator function is excuting')    return func@decdef target():
    print('excute target()')    
def main():
    passif __name__ == '__main__':
    main()

执行结果

the decorator function is excuting

也就是说不管有没有调用target函数, target = dec(target)都会在一开始马上执行.

另外装饰器还可以嵌套使用, 比如:

@deco1@deco2def target():
    pass#等价于def target():
    passtarget = deco1(deco2(target))

实现

首先是一个打印日志的装饰器, 输出函数名称, 传入的参数, 返回值

import functoolsdef log(func):    @functools.wraps(func)
    def wrapper(*args, **kw):
        res = func(*args, **kw)
        print('excute %s(), ' % func.__name__, 'args:', args, kw,', res:', res)        return res    return wrapper@logdef add(a, b):
    return a + bdef main():
    res = add(4, 5)
    print(res)
    print(add.__name__)if __name__ == '__main__':
    main()    
'''
excute add(),  args: (4, 5) {} , res: 9
9
add
'''

注意到我这里使用了@functools.wraps(func), 它可以让wrapper.__name__ = func.__name__. 如果不加, 那么print(add.__name__)的结果将是wrapper.

另外一个例子, 记录函数运行时间

import functools, timedef clock(func):    @functools.wraps(func)
    def clocks(*args, **kw):
        start = time.perf_counter()
        res = func(*args, **kw)
        elapsed = time.perf_counter() - start
        print('%s() excuted for %fs' % (func.__name__, elapsed))        return res    return clocks@clockdef snooze(seconds):
    time.sleep(seconds)def main():
    snooze(3)   

if __name__ == '__main__':
    main()'''
snooze() excuted for 3.001641s
'''



作者:前几
链接:https://www.jianshu.com/p/8d1410760809


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消