装饰器补充知识点_ @functools.wraps(func)
Posted mengchangxin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了装饰器补充知识点_ @functools.wraps(func)相关的知识,希望对你有一定的参考价值。
1 # -*- coding: utf-8 -*- 2 3 def log(func): 4 def wrapper(*args,**kwargs): 5 print(‘这个函数是 %s()‘%func.__name__) 6 return func(*args,**kwargs) 7 8 return wrapper 9 # import functools 10 # def log(text): 11 # def decorator(func): 12 # @functools.wraps(func) 13 # def wrapper(*args, **kw): 14 # #wrapper.__name__ = func.__name__ 15 # print(‘%s 这个函数是 %s():‘ % (text, func.__name__)) 16 # 17 # return func(*args, **kw) 18 # return wrapper 19 # return decorator 20 21 # @log(‘hello‘) #now=log(‘hello‘)(now) 22 @log 23 def now(): 24 print(‘2018-06-30‘) 25 return 1 26 27 print(now()) 28 print(now.__name__)
结果:
这个函数是 now() 2018-06-30 1 wrapper
以上两种decorator的定义都没有问题,但还差最后一步。因为我们讲了函数也是对象,它有__name__
等属性,但你去看经过decorator装饰之后的函数,它们的__name__
已经从原来的‘now‘
变成了‘wrapper‘
:
因为返回的那个wrapper()
函数名字就是‘wrapper‘
,所以,需要把原始函数的__name__
等属性复制到wrapper()
函数中,否则,有些依赖函数签名的代码执行就会出错。
# -*- coding: utf-8 -*- def log(func): def wrapper(*args,**kwargs): wrapper.__name__ = func.__name__ print(‘这个函数是 %s()‘%func.__name__) return func(*args,**kwargs) return wrapper @log def now(): print(‘2018-06-30‘) return 1 print(now()) print(now.__name__)
结果:
这个函数是 now() 2018-06-30 1 now
不需要编写wrapper.__name__ = func.__name__
这样的代码,Python内置的functools.wraps
就是干这个事的,所以,一个完整的decorator的写法如下:
1 # -*- coding: utf-8 -*- 2 import functools 3 def log(func): 4 @functools.wraps(func) 5 def wrapper(*args,**kwargs): 6 # wrapper.__name__ = func.__name__ 7 print(‘这个函数是 %s()‘%func.__name__) 8 return func(*args,**kwargs) 9 10 return wrapper 11 12 @log 13 def now(): 14 print(‘2018-06-30‘) 15 return 1 16 17 print(now()) 18 print(now.__name__)
结果:
这个函数是 now() 2018-06-30 1 now
import functools
是导入functools
模块。模块的概念稍候讲解。现在,只需记住在定义wrapper()
的前面加上@functools.wraps(func)
即可。
以上是关于装饰器补充知识点_ @functools.wraps(func)的主要内容,如果未能解决你的问题,请参考以下文章