Ce diaporama a bien été signalé.
Nous utilisons votre profil LinkedIn et vos données d’activité pour vous proposer des publicités personnalisées et pertinentes. Vous pouvez changer vos préférences de publicités à tout moment.

類別的繼承

894 vues

Publié le

《Python 3.5 技術手冊》第 6 章投影片

Publié dans : Logiciels
  • Soyez le premier à commenter

類別的繼承

  1. 1. 6. 類別的繼承 • 學習目標 – 瞭解繼承目的 – 認識鴨子定型 – 重新定義方法 – 認識 object – 建立、尋找文件資源
  2. 2. 繼承共同行為
  3. 3. • 重複在程式設計上,就是不好的訊號
  4. 4. 鴨子定型
  5. 5. • 動態定型語言界流行的鴨子定型 – 如果它走路像個鴨子,游泳像個鴨子,叫聲像 個鴨子,那它就是鴨子。 • 思考物件的行為,而不是物件的種類 • 具有比較高的通用性
  6. 6. 重新定義方法 • 在多數的情況下,檢查型態而給予不同的 流程行為,對於程式的維護性有著不良的 影響,應該避免:
  7. 7. • 在繼承後若打算基於父類別的方法實作來 重新定義某個方法,可以使用 super() 來 呼叫父類別方法:
  8. 8. 定義抽象方法 • 如果希望子類別在繼承之後,一定要實作 的方法 – 在父類別中指定 metaclass 為 abc 模組的 ABCMeta 類別 – 在指定的方法上標註 abc 模組的 @abstractmethod 來達到需求
  9. 9. • 如上定義就不能使用 Role 來建構物件了,否 則會發生 TypeError • 若類別繼承了 Role 類別,沒有實作fight() 方法,在實例化時也會發生 TypeError:
  10. 10. 初識 object 與 super() • 若沒有指定父類別,那麼就是繼承 object 類別
  11. 11. • 若沒有定義的方法,某些場合下必須呼叫 時,就會看看父類別中是否有定義 • 如果定義了自己的方法,那麼就會以你定 義的為主,不會主動呼叫父類別的方法
  12. 12. Rich comparison 方法 • object 類別定義了__lt__()、 __le__()、__eq__()、__ne__()、 __gt__()、__ge__() • 定義了物件之間使用<、<=、==、!=、>、 >=等比較時,應該要有的比較結果
  13. 13. • 想要能使用==來比較兩個物件是否相等, 必須定義 __eq__() 方法 • __ne__() 預設會呼叫 __eq__() 並反 相其結果 • object 定義的 __eq__() 方法,預設 是使用 is 來比較兩個物件
  14. 14. • 實作 __eq__() 時通常也會實作 __hash__() • __lt__() 與 __gt__() 互補,而 __le__() 與 __ge__() 互補 • 基本上只要定義 __gt__()、__ge__() 就可以
  15. 15. • 真的需要定義這整組方法的行為,可以使 用 functools.total_ordering
  16. 16. 使用 enum 列舉 • 透過 dict 列舉:
  17. 17. • 透過類別列舉:
  18. 18. • 從 Python 3.4 開始新增了 enum 模組
  19. 19. • 列舉物件上具有 name 與 value,可用來 取得列舉名稱與列舉值 • 也可以使用 [] 指定列舉名稱取得列舉物件。
  20. 20. • 可以使用 for in 來迭代列舉: • 繼承 Enum 或 IntEnum 類別定義列舉時,列 舉名稱不得重複,然而,列舉值可以重複。
  21. 21. • 如果想要在列舉時值不得重複,可以在類 別上加註 enum 模組的 @unique
  22. 22. 多重繼承 • 可以進行多重繼承,也就是一次繼承兩個 父類別的程式碼定義 • 父類別之間使用逗號作為區隔
  23. 23. • 如果繼承時多個父類別中有相同的方法名 稱,就要注意搜尋的順序 • 基本上是從子類別開始尋找名稱,接著是 同階層父類別由左至右搜尋,再至更上層 • 同一階層父類別由左至右搜尋,直到達到 頂層為止
  24. 24. • 一個子類別在尋找指定的屬性或方法名稱 時,會依據類別的 __mro__ 屬性的 tuple 中元素順序尋找 • MRO 全名是 Method Resolution Order, • 如果想要知道直接父類別的話,則可以透 過類別的__bases__來得知
  25. 25. • __mro__ 是唯讀屬性 • 改變 __bases__ 來改變直接父類別,從而 使得 __mro__ 的內容也跟著變動
  26. 26. • 如果定義類別時,python 直譯器無法生成 __mro__,會引發 TypeError
  27. 27. • 子類別繼承兩個父類別的順序,會決定抽 象方法是否得到實作 • 判定一個抽象方法是否有實作,也是依照 __mro__中類別的順序
  28. 28. 建立 ABC • 多重繼承的能力,通常建議只用來繼承 ABC,也就是抽象基礎類別 • 一個抽象基礎類別,不會定義屬性,也不 會有 __init__() 定義
  29. 29. • 來考慮一個 Ball 類別
  30. 30. 探討 super() • 無引數 super()呼叫,是 super(__class__, <first argument>) 的簡便方法 • 在一個綁定方法中,就相當於使用 super(__class__, self) • 在 @classmethod 標註的方法中,就相 當於呼叫super(__class__, clz)。
  31. 31. • 呼叫 super(type, obj) 時,會使用 obj 的類別之 __mro__ 清單 • 從指定的 type 之下個類別開始查找,看 看是否有指定的方法 – 若有的話,將 obj 當作是呼叫方法的首引數
  32. 32. • 呼叫 super(type, type2) 時,會使 用 type2 的 __mro__ 清單 • 從指定的 type 之下個類別開始查找,看 看是否有指定的方法,若有的話,將 type2 當作是呼叫方法的第一個引數
  33. 33. • @staticmethod 標註的方法呢?
  34. 34. DocStrings • 標準程式庫原始碼本身就附有文件
  35. 35. • 想為自訂函式定義 DocStrings: • 在函式、類別或模組定義的一開頭,使用 ''' 包括起來的多行字串,會成為函式、 類別或模組的 __doc__ 屬性值
  36. 36. • 慣例上,單行的 DocStrings 會是在一行中 使用 ''' 左右含括起來 • 函式或方法中的 DocStrings 若是多行字串, ''' 緊接的第一行,會是函式的簡短描述 • 之後空一行後,才是參數或其他相關說明, 最後換一行並縮排結束
  37. 37. • 如果是類別或模組的多行 DocStrings,會 是在 ''' 後馬上換行,以相同層次縮排
  38. 38. • 如果想針對套件來撰寫 DocStrings
  39. 39. 查詢官方文件

×