鴨子型別(duck typing)

2021-09-02 05:27:59 字數 1515 閱讀 1764

鴨子型別(duck typing)

在程式設計中,鴨子型別(duck typing)是動態型別的一種風格。

在這種風格中,乙個物件有效的語義,不是由繼承自特定的類或實現特定的介面,而是由當前方法和屬性的集合決定。

當看到乙隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這只鳥就可以被稱為鴨子。

在鴨子型別中,關注的不是物件的型別本身,而是它是如何使用的。

例如,在不使用鴨子型別的語言中,我們可以編寫乙個函式,它接受乙個型別為鴨子的物件,並呼叫它的走和叫方法。在使用鴨子型別的語言中,這樣的乙個函式可以接受乙個任意型別的物件,並呼叫它的走和叫方法。如果這些需要被呼叫的方法不存在,那麼將引發乙個執行時錯誤。任何擁有這樣的正確的走和叫方法的物件都可被函式接受的這種行為引出了以上表述,這種決定型別的方式因此得名。

鴨子型別通常得益於不測試方法和函式中引數的型別,而是依賴文件、清晰的**和測試來確保正確使用。

從靜態型別語言轉向動態型別語言的使用者通常試圖新增一些靜態的(在執行之前的)型別檢查,從而影響了鴨子型別的益處和可伸縮性,並約束了語言的動態特性(python 文件中有一句:鴨子型別應避免使用 type() 或 isinstance() 等測試型別是否合法)。

看下邊一段**:

# i love fishc.com!

class duck:

def quack(self):

print("呱呱呱!")

def feathers(self):

print("這個鴨子擁有灰白灰白的羽毛。")

class person:

def quack(self):

print("你才是鴨子你們全家人是鴨子!")

def feathers(self):

print("這個人穿著一件鴨絨大衣。")

def in_the_forest(duck):

duck.quack()

duck.feathers()

def game():

donald = duck()

john = person()

in_the_forest(donald)

in_the_forest(john)

game()

從**可以看出 python 是鴨子型別的風格呢? 

in_the_forest() 函式對引數 duck 只有乙個要求:就是可以實現 quack() 和 feathers() 方法。然而 duck 類和 person 類都實現了 quack() 和 feathers() 方法,因此它們的例項物件 donald 和 john 都可以用作 in_the_forest() 的引數。這就是鴨子型別。

我們可以看出,鴨子型別給予 python 這樣的動態語言以多型。 但是這種多型的實現完全由程式設計師來約束強制實現(文件、清晰的**和測試),並沒有語言上的約束(如 c++ 繼承和虛函式)。 因此這種方法即靈活,又提高了對程式設計師的要求。

鴨子型別(wiki)

在程式設計中,鴨子型別 英語 duck typing 是動態型別的一種風格。在這種風格中,乙個物件有效的語義,不是由繼承自特定的類或實現特定的介面,而是由當前方法和屬性的集合決定。這個概念的名字 於由james whitcomb riley提出的鴨子測試 見下面的 歷史 章節 鴨子測試 可以這樣表述...

鴨子型別(wiki)

在程式設計中,鴨子型別 英語 duck typing 是動態型別的一種風格。在這種風格中,乙個物件有效的語義,不是由繼承自特定的類或實現特定的介面,而是由當前方法和屬性的集合決定。這個概念的名字 於由james whitcomb riley提出的鴨子測試 見下面的 歷史 章節 鴨子測試 可以這樣表述...

python的鴨子型別

這次簡單介紹下 鴨子型別的概念。當看到乙隻鳥走起來像鴨子 游泳起來像鴨子 叫起來也像鴨子,那麼這只鳥就可以被稱為鴨子。鴨子型別關注點在物件的行為,而不是型別。在 python 和 go 中都可以實現鴨子型別。示例 如下 class duck def init self,name self.name ...