1. 程式人生 > >python利用類裝飾器給類定義打補丁

python利用類裝飾器給類定義打補丁

我們希望檢查或者改寫一部分類的定義,以此來修改類的行為,但是不想通過繼承或者元類的方式來做。

    如果希望解決這個問題,那麼類裝飾器絕對是首選。

    下面這個示例演示瞭如何使用類裝飾器來重寫__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學習資料、技術乾貨。分享見解,共同成長。

關注公眾號,免費獲取眾多電子版經典教材。