Python如何解除一個(gè)裝飾器
問(wèn)題
一個(gè)裝飾器已經(jīng)作用在一個(gè)函數(shù)上,你想撤銷它,直接訪問(wèn)原始的未包裝的那個(gè)函數(shù)。
解決方案
假設(shè)裝飾器是通過(guò) @wraps 來(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 wrapsdef decorator1(func): @wraps(func) def wrapper(*args, **kwargs): print(’Decorator 1’) return func(*args, **kwargs) return wrapperdef decorator2(func): @wraps(func) def wrapper(*args, **kwargs): print(’Decorator 2’) return func(*args, **kwargs) return wrapper@decorator1@decorator2def add(x, y): return x + y
下面我們?cè)赑ython3.3下測(cè)試:
>>> add(2, 3)Decorator 1Decorator 25>>> add.__wrapped__(2, 3)5>>>
下面我們?cè)赑ython3.4下測(cè)試:
>>> add(2, 3)Decorator 1Decorator 25>>> add.__wrapped__(2, 3)Decorator 25>>>
最后要說(shuō)的是,并不是所有的裝飾器都使用了 @wraps ,因此這里的方案并不全部適用。 特別的,內(nèi)置的裝飾器 @staticmethod 和 @classmethod 就沒(méi)有遵循這個(gè)約定 (它們把原始函數(shù)存儲(chǔ)在屬性 __func__ 中)。
以上就是Python如何解除一個(gè)裝飾器的詳細(xì)內(nèi)容,更多關(guān)于Python 解除裝飾器的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. nestjs實(shí)現(xiàn)圖形校驗(yàn)和單點(diǎn)登錄的示例代碼2. html小技巧之td,div標(biāo)簽里內(nèi)容不換行3. 以PHP代碼為實(shí)例詳解RabbitMQ消息隊(duì)列中間件的6種模式4. laravel ajax curd 搜索登錄判斷功能的實(shí)現(xiàn)5. python爬蟲(chóng)實(shí)戰(zhàn)之制作屬于自己的一個(gè)IP代理模塊6. Python 如何將integer轉(zhuǎn)化為羅馬數(shù)(3999以內(nèi))7. 將properties文件的配置設(shè)置為整個(gè)Web應(yīng)用的全局變量實(shí)現(xiàn)方法8. python實(shí)現(xiàn)自動(dòng)化辦公郵件合并功能9. Echarts通過(guò)dataset數(shù)據(jù)集實(shí)現(xiàn)創(chuàng)建單軸散點(diǎn)圖10. css進(jìn)階學(xué)習(xí) 選擇符
