装饰器补充知识点_ @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)的主要内容,如果未能解决你的问题,请参考以下文章

day20 装饰器补充

Python基础day-8[装饰器补充,迭代器(未完)]

Python学习笔记6-python函数补充装饰器模块

在 Sphinx 文档中保留包装/装饰 Python 函数的默认参数

python之有参装饰器_02

python-day5-装饰器补充模块字符串格式化和序列化