前一講,你肯定注意到了乙個有點奇怪的細節:複數形式的 __bases__ 。前面說過,你可使用它來獲悉類的基類,而基類可能有多個。為說明如何繼承多個類,下面來建立幾個類。
class calculator:
def calculate(self, expression):
self.value = eval(expression)
class talker:
def talk(self):
print('hi, my value is', self.value)
class talkingcalculator(calculator, talker):
pass
子類 talkingcalculator 本身無所作為,其所有的行為都是從超類那裡繼承的。關鍵是通過從calculator 那裡繼承 calculate ,並從 talker 那裡繼承 talk ,它成了會說話的計算器。
>>> tc = talkingcalculator()
>>> tc.calculate('1 + 2 * 3')
>>> tc.talk()
hi, my value is 7
這被稱為多重繼承,是乙個功能強大的工具。然而,除非萬不得已,否則應避免使用多重繼承,因為在有些情況下,它可能帶來意外的「併發症」。
使用多重繼承時,有一點務必注意:如果多個超類以不同的方式實現了同乙個方法(即有多個同名方法),必須在 class 語句中小心排列這些超類,因為位於前面的類的方法將覆蓋位於後面的類的方法。因此,在前面的示例中,如果 calculator 類包含方法 talk ,那麼這個方法將覆蓋 talker類的方法 talk (導致它不可訪問)。如果像下面這樣反轉超類的排列順序:
class talkingcalculator(talker, calculator): pass
將導致 talker 的方法 talk 是可以訪問的。多個超類的超類相同時,查詢特定方法或屬性時訪問超類的順序稱為方法解析順序(mro),它使用的演算法非常複雜。所幸其效果很好,你可能根本無需擔心。
>>> hasattr(tc, 'talk')
true
>>> hasattr(tc, 'fnord')
false
在上述**中,你發現 tc (本章前面介紹的 talkingcalculator 類的例項)包含屬性 talk (指向乙個方法),但沒有屬性 fnord 。如果你願意,還可以檢查屬性 talk 是否是可呼叫的。
>>> callable(getattr(tc, 'talk', none))
true
>>> callable(getattr(tc, 'fnord', none))
false
請注意,這裡沒有在 if 語句中使用 hasattr 並直接訪問屬性,而是使用了 getattr (它讓我能夠指定屬性不存在時使用的預設值,這裡為 none ),然後對返回的物件呼叫 callable 。
setattr 與 getattr 功能相反,可用於設定物件的屬性:
>>> setattr(tc, 'name', 'mr. gumby')
>>> tc.name
'mr. gumby'
要檢視物件中儲存的所有值,可檢查其 __dict__ 屬性。如果要確定物件是由什麼組成的,應研究模組 inspect 。這個模組主要供高階使用者建立物件瀏覽器(讓使用者能夠以圖形方式瀏覽python物件的程式)以及其他需要這種功能的類似程式。 Python入門到精通三天速成第二講 類與繼承
子類擴充套件了超類 父類 的定義。要指定超類,可在 class 語句中的類名後加上超類名,並將其用圓括號括起。class filter def init self self.blocked def filter self,sequence return x for x in sequence if ...
Python從入門到精通
大神請繞路而走,本文適合入門小白 python基礎 python 資料型別和變數 python 字串和編碼 python 使用list和tuple python 條件判斷和迴圈 python 使用dict和set 函式python 呼叫函式 python 定義函式 python 函式的引數 pyth...
flutter從入門到精通三
flutter可以通過一套 執行在多個平台上,包括移動,web,桌面,嵌入式,但是在 web 平台的支援尚未達到 beta 階段,請不要用在生產環節,在閱讀文件時候,推薦大家閱讀 這是和官方文件同步的中文 減少學習的成本 下面所有的 和案例都是基於編輯器vs code進行編輯,使用該編輯器和編輯器外...