装饰器补充知识点_ @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)即可。

猜你喜欢

转载自www.cnblogs.com/Mengchangxin/p/9248238.html