python裝飾器@wraps作用 修複被裝飾後的函數名等屬性的改變 Python裝飾器(decorator)在實現的時候,被裝飾後的函數其實已經是另外一個函數了(函數名等函數屬性會發生改變), 為了不影響,Python的functools包中提供了一個叫wraps的decorator來消除這樣的副 ...
python裝飾器@wraps作用-修複被裝飾後的函數名等屬性的改變
Python裝飾器(decorator)在實現的時候,被裝飾後的函數其實已經是另外一個函數了(函數名等函數屬性會發生改變),
為了不影響,Python的functools包中提供了一個叫wraps的decorator來消除這樣的副作用。寫一個decorator的時候,最好在實現之前加上functools的wrap,
它能保留原有函數的名稱和docstring。
未加@wraps的時候:
from functools import wraps
def wrapper(func):
# @wraps(func)
def inner(*args, **kwargs):
print("裝飾器工作中...")
func(*args, **kwargs)
return inner
@wrapper
def f1(arg):
"""
這是一個測試裝飾器修複技術的函數
:param arg: 隨便傳
:return: 沒有
"""
print(arg)
f1('呵呵')
print(f1.__name__,f1.__doc__)
列印結果是:
但是加上@wraps以後:
from functools import wraps
def wrapper(func):
@wraps(func)
def inner(*args, **kwargs):
print("裝飾器工作中...")
func(*args, **kwargs)
return inner
@wrapper
def f1(arg):
"""
這是一個測試裝飾器修複技術的函數
:param arg: 隨便傳
:return: 沒有
"""
print(arg)
f1('呵呵')
print(f1.__name__,f1.__doc__)
列印結果是:
其中主要的就是兩個變數:
1、顯示 正在執行的函數的名稱 f.name
2、顯示 正在執行的函數的註釋 f.doc
簡單來說就是:
如果沒使用@wraps,當A調用了裝飾器B的話,即使A.name,返回的會是裝飾器B的函數名稱,而不是A的函數名稱
如果使用了@wraps,當A調用了裝飾器B的話,A.__ name__返回的會是A函數的名稱,而不是飾器B的名稱,
這也即使常說的@wraps是裝飾器的修複技術,
實際就是修複還原了A的__ name__變數,同理__ doc__變數也是一樣。