Python如何解除一個裝飾器
阿新 • • 發佈:2020-08-10
問題
一個裝飾器已經作用在一個函式上,你想撤銷它,直接訪問原始的未包裝的那個函式。
解決方案
假設裝飾器是通過 @wraps 來實現的,那麼你可以通過訪問 __wrapped__ 屬性來訪問原始函式:
>>> @somedecorator >>> def add(x,y): ... return x + y ... >>> orig_add = add.__wrapped__ >>> orig_add(3,4) 7 >>>
討論
直接訪問未包裝的原始函式在除錯、內省和其他函式操作時是很有用的。 但是我們這裡的方案僅僅適用於在包裝器中正確使用了 @wraps
__wrapped__
屬性的情況。
如果有多個包裝器,那麼訪問 __wrapped__
屬性的行為是不可預知的,應該避免這樣做。 在Python3.3中,它會略過所有的包裝層,比如,假如你有如下的程式碼:
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
下面我們在Python3.3下測試:
>>> add(2,3) Decorator 1 Decorator 2 5 >>> add.__wrapped__(2,3) 5 >>>
下面我們在Python3.4下測試:
>>> add(2,3) Decorator 2 5 >>>
最後要說的是,並不是所有的裝飾器都使用了 @wraps
,因此這裡的方案並不全部適用。 特別的,內建的裝飾器 @staticmethod
和 @classmethod
就沒有遵循這個約定 (它們把原始函式儲存在屬性 __func__
以上就是Python如何解除一個裝飾器的詳細內容,更多關於Python 解除裝飾器的資料請關注我們其它相關文章!