装饰器的本质是一个闭包函数,作用在于不改变原函数功能和调用方法的基础上给它添加额外的功能.装饰器在装饰一个函数时,原函数就成了一个新的函数,也就是说其属性会发生变化,所以为了不改变原函数的属性,我们会调用functools中的wraps装饰器来保证原函数的属性不变.下边以一个简单的例子展示wraps装饰器的作用 :
在有wraps的情况下:
from functools import wraps
def test(func):
@wraps(func)
def inner():
'装饰器'
print(inner.__name__,inner.__doc__)
return func()
return inner
@test
def func():
'原函数'
print(11111)
print(func.__name__,func.__doc__)
func()
# func 原函数
# 11111
# func 原函数
很明显在使用了wraps的情况下当调用func函数时,func的属性并没有说明变化.
在没有wraps装饰的情况下:
from functools import wraps
def test(func):
# @wraps(func)
def inner():
'装饰器'
print(inner.__name__,inner.__doc__)
return func()
return inner
@test
def func():
'原函数'
print(11111)
print(func.__name__,func.__doc__)
func()
# inner 装饰器
# 11111
# inner 装饰器
虽然func函数本身的功能没有发生变化,但是__name__已经发生变化,其属性也变成inner函数的属性.
综上,在进行装饰器的操作时,最好加上wraps装饰器,保证原函数在执行时不会发生异常.