問題
乙個裝飾器已經作用在乙個函式上,你想撤銷它,直接訪問原始的未包裝的那個函式。
解決方案
假設裝飾器是通過 @wraps 來實現的,那麼你可以通過訪問 __wrapped__ 屬性來訪問原始函式:
>>> @somedecorator
>>> def add(x, y):
... return x + y
...>>> orig_add = add.__wrapped__
>>> orig_add(3, 4)
7>>>
討論直接訪問未包裝的原始函式在除錯、內省和其他函式操作時是很有用的。 但是我們這裡的方案僅僅適用於在包裝器中正確使用了@wraps或者xflkuoec直接設定了__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 1
decorator 2
5>>> add.__wrapped__(2, 3)
deco 2
5>>>
最後要說的是,並不是所有的裝飾器都使用了@wraps,因此這裡的方案並不全部適用。 特別的,內建的裝飾器@staticmethod和@classmethod就沒有遵循這個約定 (它們把原始函式儲存在屬性__func__中)。
裝飾器如何裝飾乙個函式
裝飾器如何裝飾乙個函式?今天番茄加速就來講一下。printstar函式接收乙個函式f,返回值也是乙個函式,所以滿足裝飾器的結構要求,所以printstar是乙個裝飾器。def printstar f def g print 20 f print 20 return g printstar裝飾器實現f...
乙個裝飾器裝飾乙個函式
2 如果鍵不存在,則新增到字典中。請使用裝飾器來實現,順便複習下 args和 kwargs的用法 a defselect func def inner args,kwargs if len args 0 if kwargs key in kwargs data print 鍵存在 else func...
Python實現乙個裝飾器
在不改變原函式的呼叫以及內部 情況下,為其新增新功能的函式。實現乙個裝飾器 def print func name func 提供舊功能 print func.name 新功能 return func args,kwargs 舊功能 print func name say hello print f...