W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
一個(gè)裝飾器已經(jīng)作用在一個(gè)函數(shù)上,你想撤銷它,直接訪問(wèn)原始的未包裝的那個(gè)函數(shù)。
假設(shè)裝飾器是通過(guò) @wraps
(參考9.2小節(jié))來(lái)實(shí)現(xiàn)的,那么你可以通過(guò)訪問(wèn) __wrapped__
屬性來(lái)訪問(wèn)原始函數(shù):
>>> @somedecorator
>>> def add(x, y):
... return x + y
...
>>> orig_add = add.__wrapped__
>>> orig_add(3, 4)
7
>>>
直接訪問(wèn)未包裝的原始函數(shù)在調(diào)試、內(nèi)省和其他函數(shù)操作時(shí)是很有用的。但是我們這里的方案僅僅適用于在包裝器中正確使用了 @wraps
或者直接設(shè)置了 __wrapped__
屬性的情況。
如果有多個(gè)包裝器,那么訪問(wèn) __wrapped__
屬性的行為是不可預(yù)知的,應(yīng)該避免這樣做。在Python3.3中,它會(huì)略過(guò)所有的包裝層,比如,假如你有如下的代碼:
from functools import wraps
def decorator1(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('Decorator 1')
return func(*args, **kwargs)
return wrapper
def decorator2(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('Decorator 2')
return func(*args, **kwargs)
return wrapper
@decorator1
@decorator2
def add(x, y):
return x + y
下面我們?cè)赑ython3.3下測(cè)試:
>>> add(2, 3)
Decorator 1
Decorator 2
5
>>> add.__wrapped__(2, 3)
5
>>>
下面我們?cè)赑ython3.4下測(cè)試:
>>> add(2, 3)
Decorator 1
Decorator 2
5
>>> add.__wrapped__(2, 3)
Decorator 2
5
>>>
最后要說(shuō)的是,并不是所有的裝飾器都使用了 @wraps
,因此這里的方案并不全部適用。特別的,內(nèi)置的裝飾器 @staticmethod
和 @classmethod
就沒(méi)有遵循這個(gè)約定(它們把原始函數(shù)存儲(chǔ)在屬性 __func__
中)。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: