天天看點

鴨子類型 - Duck Typing

1 還是先看定義 duck typing,
  2     鴨子類型是多态(polymorphism)的一種形式.在這種形式中,不管對象屬于哪個,
  3     也不管聲明的具體接口是什麼,隻要對象實作了相應的方法,函數就可以在對象上執行操作.
  4     即忽略對象的真正類型,轉而關注對象有沒有實作所需的方法、簽名和語義.
  5         duck typing
  6             A form of polymorphism where functions
  7             operate on any object that implements the
  8             appropriate methods, regardless of their
  9             classes or explicit interface declarations.
 10 
 11     Wikipedia 是這樣描述 duck typing 的,
 12         在計算機語言中, duk typing 是一個類型測試的一個具體應用.
 13         是将對類型的檢查推遲到代碼運作的時候,由動态類型(dynamic typing)
 14         或者檢討(reflection)實作. duck typing 應用在通過應用規則/協定(protocol)
 15         建立一個适合的對象 object.
 16         '如果它走起步來像鴨子,并且叫聲像鴨子, 那個它一定是一隻鴨子.'
 17         對于一般類型 normal typing, 假定一個對象的 suitability 隻有該對象的類型決定.
 18         然而,對于 duck typing 來說, 一個對象 object 的 suitability 是通過該對象是否
 19         實作了特定的方法跟屬性來決定 certain methods and properties, 而不是由該對象
 20         的來類型決定.
 21 
 22         注,
 23             In computer science, reflection is the ability of a computer program to
 24             examine,introspect, and modify its own structure and behavior at runtime.
 25 
 26         From Wikipedia,
 27             In computer programming, duck typing is an application of the duck test
 28             in type safety.It requires that type checking be deferred to runtime,
 29             and is implemented by means of dynamic typing or reflection.
 30             Duck typing is concerned with establishing the suitability of an object
 31             for some purpose, using the principle, "If it walks like a duck and it
 32             quacks like a duck, then it must be a duck." With normal typing,
 33             suitability is assumed to be determined by an object's type only.
 34             In duck typing, an object's suitability is determined by the presence
 35             of certain methods and properties (with appropriate meaning),
 36             rather than the actual type of the object.
 37 
 38 
 39     鴨子類型的起源 Origins of duck-typing,
 40         現在谷歌工程師,Python 社群重要貢獻者之一: Alex Martelli 說到,
 41             我相信是 Ruby 社群推動了 duck typing 這個術語的流行.
 42             但是這個duck typing 這種表達在 Ruby 和 Python 火之前,
 43             就是在Python 的讨論中使用過.
 44 
 45         根據 Wikipedia, duck typing 這一術語最早被 Alex Martelli 在 2000 所使用.
 46         Related Link of Wikipedia - https://en.wikipedia.org/wiki/Duck_typing
 47 
 48     歸功于 python 的 資料類型 data model, 你的使用者自定義類型的行為可以像 built-in 類型一樣自然。
 49     這并不需要通過繼承 inheritance 來獲得. 本着 duck typing, 可以在對象中隻實作需要的方法, 就能
 50     保證保證對象的行為符合預期. 對 Python 來說,這基本上是指避免使用 isinstance 檢查對象的類,
 51     更别提 type(foo) is bar 這種更糟的檢查方式了,這樣做沒有任何好處,甚至禁止最簡單的繼承方式.
 52     具體使用時,上述建議有一個常見的例外:有些 Python API 接受一個字元串或字元串序列;
 53     如果隻有一個字元串,可以把它放到清單中,進而簡化處理. 因為字元串是序列類型,
 54     是以為了把它和其他不可變序列區分開,最簡單的方式是使用 isinstance(x, str) 檢查.
 55     另一方面,如果必須強制執行 API 契約,通常可以使用 isinstance 檢查抽象基類。
 56 
 57     在看例子之前, 先看簡略一下兒 協定 protocol 相關内容,
 58         在 Python 中建立功能完善的序列類型無需使用繼承, 隻需實作符合序列協定的方法.
 59         在面向對象程式設計中,協定是非正式的接口,隻在文檔中定義,在代碼中不定義.
 60         例如,Python 的序列協定隻需要 __len__ 和 __getitem__ 兩個方法.
 61         任對象/類型(A)隻要使用标準的簽名和語義實作了這兩個方法,就能用在任何期待序列的地方,
 62         然而A 是不是哪個類的子類無關緊要,隻要提供了所需的方法即可.這就是 python 序列協定.
 63         協定是非正式的,沒有強制力,是以如果你知道類的具體使用場景,通常隻需要實作一個協定的部分.
 64         例如,為了支援疊代,隻需實作 __getitem__ 方法,沒必要提供 __len__方法.
 65 
 66         經典示例, duck typing 處理一個字元串 string 或 可疊代字元串 iterable of strings
 67             try:                                                      #1
 68                 field_names = field_names.replace(',', ' ').split()   #2
 69             except AttributeError:                                    #3
 70                 pass                                                  #4
 71             field_names = tuple(field_names)                          #5
 72 
 73             #1, 假定 field_names 是一個字元串 string. EAFP, it’s easier to ask forgiveness than permission
 74             #2, 将 field_names 中的 ',' 替換成空格 ' ' 并 split, 将結果放到 list 中
 75             #3, sorry, field_names 并不像一個 str, field_names 不能 .replace 或者 .replace 後傳回的結果不能 .split()
 76             #4, 這裡我men假設 新的 field_names 是一個可疊代對象
 77             #5, 確定新的 field_names 是一個可疊代對象, 同僚儲存一個 copy - create 一個 tuple
 78 
 79             field_names = 'abc'                                       #6
 80             field_names = 'A,B,C'                                     #7
 81             try:
 82                 field_names = field_names.replace(',', ' ').split()
 83             except AttributeError:
 84                 pass
 85             print(field_names)
 86             field_names = tuple(field_names)
 87             print(field_names)
 88             for item in field_names:
 89                 print(item)
 90 
 91             Output,
 92                 ['abc']            #6
 93                 ('abc',)           #6
 94                 abc                #6
 95                 --------------
 96                 ['A', 'B', 'C']    #7
 97                 ('A', 'B', 'C')    #7
 98                 A                  #7
 99                 B                  #7
100                 C                  #7
101 
102         結論,
103             Summarize, Outside of frameworks, duck typing is often sim‐pler and more flexible than type checks.      

轉載于:https://www.cnblogs.com/zzyzz/p/7723272.html