在程式設計中,鴨子類型(英文:duck typing)是動態類型的風格。在這種風格中,一個物件有效的語義,不是由繼承自特定的類別或實作特定的接口,而是由當前方法和屬性的集合決定。
這個概念的名字來自由James Whitcomb Riley提出的鴨子測試,「鴨子測試」可以這樣表達:
「當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就可以被稱為鴨子。例如,在不使用鴨子類型的語言中,我們可以寫一個函數,它接受一個類型為鴨的對象,並呼叫它的走和叫方法。在使用鴨子類型的語言中,這樣的一個函數可以接受一個任意類型的對象,並呼叫它的走和叫方法。如果這些需要被呼叫的方法不存在,那麼將會引發一個運行時錯誤。任何擁有這樣的正確的走和叫方法的對像都可被函數接受的這種行為引出了以上表述,這種決定類型的方式因此得名。
鴨子類型通常得益於不測試方法和函數中參數的類型,而是依賴文件、清晰的程式碼和測試來確保正確使用。從靜態類型語言轉向動態類型語言的使用者通常試圖添加一些靜態的(在運行之前的)類型檢查,從而影響了鴨子類型的益處和可伸縮性,並約束了語言的動態特性。
Python程式碼範例
上面這樣說可能太空洞了。例如在Python中,有很多file-like的東西,像是StringIO,GzipFile,socket。它們有很多相同的方法,我們把它們當作文件使用。 又比如list.extend()方法中,我們並不關心它的參數是不是list,只要它是可迭代的,所以它的參數可以是list/tuple/dict/字串/生成器等.
鴨子類型在動態語言中經常使用,非常靈活,使得python不想java那樣專門去弄一大堆的設計模式。
#coding=utf-8 class Duck: def quack(self): print "Quaaaaaack!" class Bird: def quack(self): print "bird imitate duck." class Doge: def quack(self): print "doge imitate duck." def in_the_forest(duck): duck.quack() duck = Duck() bird = Bird() doge = Doge() for x in [duck, bird, doge]: in_the_forest(x)再舉個栗子,
我們來hack輸出流。
import sys sys.stdout = open('stdout.log', 'a') #只要是file-like,不管是什么类型 print 'foo' sys.stdout = sys.__stdout__ #恢复 print 'bar'這樣就把輸出流給寫入到檔案中去了。 更多詳細解釋duck typing鴨子類型程式設計與Python的實作相關文章請關注PHP中文網!