有時候,咱們想經過一個類來調用另外一個類裏的方法來處理請求,即這兩個類對象參與處理同一個請求對象,只不過一個是委託者,一個是處理者。python
好比咱們如今有一個名爲Dog的類對象,咱們但願經過它調用 voice 類產生「狗吠 」 聲,這時候就能夠採用委託模式。下面就用Python來理解這個設計模式。設計模式
Python裏,在委託者類對象中,須要這麼設計:app
1. 重寫__getattr__方法,使得委託者得到處理者的屬性。函數
2. 判斷該屬性是否爲可調用函數,若是不是則直接返回,若是是,則用 wrapper 封裝爲可調用對象。優化
以下所示:spa
class Dog: def __init__(self, voice): self.voice = voice def __getattr__(self, name): """ 重寫__getattr__方法 得到相應的屬性 Arguments: name {str} -- 目標變量/函數名 Returns: attr -- 處理者的變量/函數 """ attr = getattr(self.voice, name) if not callable(attr): return attr def wrapper(*args, **kwargs): return attr(*args, **kwargs) return wrapper
這樣作的好處是,處理者(被委託者)不須要作太多的更改,通常是一個公用類。咱們的處理者以下:設計
class voice: def __init__(self): self.p1 = 'test' def words(self, something): print("voice: %s" % something) return "voice: %s" % something
這樣就能夠經過委託者來調用另外一個類的方法來對請求進行處理:code
if __name__ == '__main__': John = Dog(voice()) John.words('汪汪')
實際上,若是你不重寫__getattr__,同樣能夠用如下的方式調用到voice類:對象
if __name__ == '__main__': John = Dog(voice()) John.voice.words('汪汪')
這兩種有什麼區別呢?使用委託模式,能夠簡化代碼,優化可讀性,你不須要再調用voice對象, 委託者本身會利用 getattr 找到相應的對象裏的方法。教程
不過,在Python裏,委託模式這樣的寫法實際上是 un-pythonic 的,由於它將調用的方法隱藏在了執行者中, 可讀性比較差。若是不是特殊須要,通常不會這麼作,這裏只是給你們展現如何用Python來理解這個設計模式。
咱們的文章到此就結束啦,若是你但願咱們今天的Python 實戰教程,請持續關注咱們,若是對你有幫助,麻煩在下面點一個贊/在看哦,有任何問題均可以在下方留言區留言,咱們都會耐心解答的!
Python實用寶典
不僅是一個寶典
歡迎關注公衆號:Python實用寶典
原文來自Python實用寶典:利用 Python 理解設計模式之委託模式