python利用類裝飾器給類定義打補丁
阿新 • • 發佈:2018-12-12
我們希望檢查或者改寫一部分類的定義,以此來修改類的行為,但是不想通過繼承或者元類的方式來做。
如果希望解決這個問題,那麼類裝飾器絕對是首選。
下面這個示例演示瞭如何使用類裝飾器來重寫__getattribute__特殊方法,併為它增加了日誌功能:
from functools import wraps
def log_getattribute(cls):
#獲取原始的實現方法
orig_getattribute = cls.__getattribute__
#定義新的實現方法,記得要返回原始的實現方法
def new_getattribute (self,name):
print("getting:",name)
return orig_getattribute(self,name)
#修改方法對映並返回
cls.__getattribute__ = new_getattribute
return cls
@log_getattribute
class A:
def __init__(self,x):
self.x = x
如果嘗試使用該方法來訪問類例項的屬性,會得到以下結果:
>>> a=A(12)
>> > a.x
getting: x
12
>>> a.spam()
getting: spam
類裝飾器往往是作為混合類或元類等高階技術的替代方案,對於本文中的問題,我們還有一種方法是使用繼承來解決:
class LoggedGetattribute:
def __getattribute__(self, name):
print("getting:",name)
return super().__getattribute__(name)
class A(LoggedGetattribute):
def __init__ (self,x):
self.x = x
def spam(self):
pass
這麼做也是可行的,這樣在父類中使用super()需要涉及到方法解析順序(MRO)、super()以及其他和繼承相關的知識。
從某些角度上來看,使用類裝飾器顯得更加直觀一些,而且不會在繼承體系中引入新的依賴關係。而且事實證明,因為不使用super()函式,所以執行速度也會更加快。
微信公眾號:進擊的程式碼Amos
每天更新Java、python學習資料、技術乾貨。分享見解,共同成長。
關注公眾號,免費獲取眾多電子版經典教材。