裝飾器的本質是一個閉包函數,作用在於不改變原函數功能和調用方法的基礎上給它添加額外的功能.裝飾器在裝飾一個函數時,原函數就成了一個新的函數,也就是說其屬性會發生變化,所以為了不改變原函數的屬性,我們會調用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裝飾器,保證原函數在執行時不會發生異常.
