鴨子打字

更新 發佈閱讀 10 分鐘

在Python官網的Glossary第一次看到「duck typing」這個詞的時候,真的是很疑惑:Python怎麼會跟鴨子扯得上關係?更疑惑的是,那還是隻會打字的鴨子!等到看完裡頭的解釋後,才知道完全會錯意了,duck還是鴨子,不過typing跟打字一點關係都沒有,而是指程式設計中,設定data type的方法,中文有人翻譯成「定型」。

其實看完官網的解釋後,並沒什麼特別的感覺,不過有句話倒是特別有印象,因為實在是太特別了,真不知道這句話跟程式語言是怎麼扯上關係的,這句話原文是:

If it looks like a duck and quacks like a duck, it must be a duck.

翻譯成中文就是:

如果牠看起來像隻鴨子,叫起來像隻鴨子,那牠就一定是隻鴨子。

好嘛!反正牠就是隻鴨子,然後呢?然後就沒有然後了,寫程式時好像也用不著,這個跟鴨子有關的詞,就這樣給拋到九霄雲外去了。偶而會想起跟鴨子有關的事,也就只有烤鴨,直到在寫Stochastic L-system時,才又注意到它,把它搞懂。

在寫Stochastic L-system時,因為每組production rule裡頭,可能包含數條規則,會使用哪條規則,是依據機率來決定。所以囉,在程式裡頭,就應該要去檢查這些規則的機率總和,是不是剛好是1。這個部分倒是不難處理,可是接著又想到,那是不是也需要去檢查這些規則的寫法,是不是符合設定好的格式?這些規則長這樣:

rule = {'F': [('G[-F]+F', 1.0)], 'G': [('GG', 0.5), ('G', 0.2), ('GGG', 0.3)]}

要檢查使用者給的規則是不是符合這樣的格式,第一步顯然應該先檢查rule的data type是不是dictionary,不過這部分的指令不熟,得查一下。

因為rule是要當成argument給送進去function裡頭,所以下關鍵字查詢的時候,就乾脆查看看別人是怎麼檢查argument的。沒想到,不少人說不要檢查argument的data type,然後提到duck typing。

說實在的,會想到要去檢查argument的data type,是因為萬一送進function的東西是有問題的,要能夠抓出來並顯示錯誤訊息。那現在說不要檢查data type是怎樣?有問題的時候怎麼辦?網路上有人的意見是說,其實啊,這個問題也沒那麼難處理,反正argument的data type不對,在某個地方一定會因為錯誤的使用方式而被抓出來。例如某個argument本來應該是一個dictionary,結果卻送了個tuple進來,用使用dictionary的方式來使用tuple,一定會出問題,而且系統也會有錯誤訊息,顯示到底是什麼問題。既然這樣,那有沒有去檢查argument的data type,其實也就沒那麼重要了。

也是啦!反正萬一argument的data type有問題,系統會告訴你,那多一事不如少一事,大可不必自己去檢查。能坐就不站,能躺就不坐,心存偷懶的心態,在寫程式的時候,有時候反而會是一種美德。不過,偷懶歸偷懶,那個跟鴨子有關的duck typing還是應該要把它搞懂。

在網路上有許多關於duck typing的文章,也有許多範例,不過總而言之,其實就是大家常說的:不管黑貓白貓,會抓老鼠的就是好貓。又是鴨子又是貓的,用個例子來說明:假設現在有三隻動物,分別叫做Black、Kitty、Dada,牠們其實是一隻狗、一隻貓,還有一隻鴨子。眾所周知,狗、貓、鴨子都會叫,而且叫聲不一樣;另外,牠們都會走路,不過鴨子除了會走之外,還會飛。這些寫成程式長這樣:

class Dog:
  def walk(self):
    print("I am a dog. See! I can walk.")
  def say(self):
    print("Woof! Woof! Woof!")

class Cat:
  def walk(self):
    print("I am a cat. See! I can walk.")
  def say(self):
    print("Meow! Meow! Meow!")

class Duck:
  def walk(self):
    print("I am a duck. See! I can walk.")
  def say(self):
    print("Quack! Quack! Quack!")
  def fly(self):
    print("I am a duck. See! I can fly.")

Black = Dog()
Kitty = Cat()
Dada = Duck()

現在問題來了,牠們三個很害羞,都把臉遮起來,讓人搞不清楚誰是誰。為了要搞清楚誰是誰,只好根據牠們會的技能來判別。判斷牠們會不會某項技能的程式長這樣:

def test_walk(animal):
  animal.walk()
def test_say(animal):
  animal.say()
def test_fly(animal):
  animal.fly()

先來看看牠們會不會走路:

test_walk(Black)
test_walk(Kitty)
test_walk(Dada)

結果

I am a dog. See! I can walk.
I am a cat. See! I can walk.
I am a duck. See! I can walk.

每個都會走路,而且都說出來牠是哪種動物。這樣就知道誰是誰了吧?那可未必!萬一牠們說謊呢?既然不確定,那再來看看牠們會不會叫好了:

test_say(Black)
test_say(Kitty)
test_say(Dada)

結果三個都會叫,而且叫聲都不一樣:

Woof! Woof! Woof!
Meow! Meow! Meow!
Quack! Quack! Quack!

這總可以了吧?這……萬一牠們都會二種語言呢?說不定狗狗Black很喜歡貓的文化,所以學會了叫「Meow」,而貓咪Kitty為了想抓鴨子,所以學會了叫「Quack」,這樣才能混入鴨群中。

這也不行、那也不行,那就看看誰會飛吧!至少知道會飛的那個是鴨子,總不可能貓和狗都可以飛上天吧。先來看看Black行不行:

test_fly(Black)

結果出現錯誤訊息,說牠是狗不會飛:

AttributeError: 'Dog' object has no attribute 'fly'

再來是Kitty

test_fly(Kitty)

一樣會有錯誤訊息,說牠是貓不會飛:

AttributeError: 'Cat' object has no attribute 'fly'

最後是Dada

test_fly(Dada)

結果,牠會飛耶!

I am a duck. See! I can fly.

所以囉,現在很確定Dada就是會飛的鴨子。

費盡千辛萬苦,總算知道誰是誰了。從這過程中,可以看得出來,test_walk、test_say、test_fly這三個function,在使用的時候,根本就不管傳給它們的argument是哪種class的instance。它們唯一在乎的,是那個object有沒有它們要用到的method。所以說,duck typing說的,就是如果有隻雞界同時精通易容跟口技的大師,哪天突然心血來潮易容成鴨子,然後改變叫聲開始像鴨子一樣呱呱叫。這時候,即使牠的嘴巴和爪子都是尖尖的,走路也不會大搖小屁屁,牠都會被當成是鴨子。這也就是說,如果目的就是要抓老鼠,不管你是黑貓或白貓,甚至是捕鼠籠或機器人,只要會抓老鼠就好,長相和身份根本就不重要!

各行各業不同領域,總是會有些字面上看來挺奇怪的術語。鴨子跟程式設計居然扯得上關係!還有啊,猜猜看,「出血」是哪個行業的術語?可別猜是醫療業!要有這麼好猜就不好玩了。答案是平面設計。第一次在平面設計的書上看到「出血」兩個字,還真是愣住了,這行業有這麼血汗嗎?等搞清楚了出血是怎麼回事,也只能翻翻白眼苦笑,這行業的人可真是幽默啊!

其實啊,看起來再奇怪的術語,都有它形成的原因和典故,說不定現在習以為常的說法,在以後的人看來也是會覺得奇奇怪怪挺無言的。現在管讓車子加速的東東叫「油門」,可是電動車又不喝油,那玩意兒該叫什麼?看來還是會油門油門一直叫下去。等到以後大家開的、騎的全都是電動車,而油車身影也從大多數人的腦海中消失,那時候應該也會有人覺得很奇怪,明明就是吃電的,怎麼會叫油門啊?

留言
avatar-img
ysf的沙龍
20會員
164內容數
寫點東西自娛娛人
ysf的沙龍的其他內容
2025/04/14
花了些時間,靜下心來,仔仔細細地研究了一番,總算把Python呼叫函數時引數的傳遞方式給徹底搞清楚了。
2025/04/14
花了些時間,靜下心來,仔仔細細地研究了一番,總算把Python呼叫函數時引數的傳遞方式給徹底搞清楚了。
2024/05/08
呼!折騰了好久,終於徹底搞清楚pygame的各個blend mode所用的計算式,到底是長啥樣子了。
2024/05/08
呼!折騰了好久,終於徹底搞清楚pygame的各個blend mode所用的計算式,到底是長啥樣子了。
2023/12/20
在寫《The Nature of Code閱讀心得筆記——使用Python實作》的[第四章]4.3節時,原書提到,在使用Java的ArrayList時,如果用迴圈一面走訪一面又移除其中的元素,那會有難以察覺的問題存在。寫個小程式測試的結果發現,Python的list也會有一樣的問題。
Thumbnail
2023/12/20
在寫《The Nature of Code閱讀心得筆記——使用Python實作》的[第四章]4.3節時,原書提到,在使用Java的ArrayList時,如果用迴圈一面走訪一面又移除其中的元素,那會有難以察覺的問題存在。寫個小程式測試的結果發現,Python的list也會有一樣的問題。
Thumbnail
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
這兩隻特別的小動物,是某日在散步途中發現的,我以他們為主角,試著揣摩牠們的心境,寫成了兩首小短詩,也藉此享受一下想像與放鬆的小確幸時光!
Thumbnail
這兩隻特別的小動物,是某日在散步途中發現的,我以他們為主角,試著揣摩牠們的心境,寫成了兩首小短詩,也藉此享受一下想像與放鬆的小確幸時光!
Thumbnail
鴨舞者穿著 白舞衣 跳著水中芭蕾 一會兒潛入水中 一會兒鑽出水面 一會兒翹起尾巴 好不美麗 池塘邊 戴著皇冠 身穿黃袍的雞國王 忍不住拍手叫好: 「咯咯咯!」
Thumbnail
鴨舞者穿著 白舞衣 跳著水中芭蕾 一會兒潛入水中 一會兒鑽出水面 一會兒翹起尾巴 好不美麗 池塘邊 戴著皇冠 身穿黃袍的雞國王 忍不住拍手叫好: 「咯咯咯!」
Thumbnail
在Python官網的Glossary第一次看到「duck typing」這個詞的時候,真的是很疑惑:Python怎麼會跟鴨子扯得上關係?更疑惑的是,那還是隻會打字的鴨子!
Thumbnail
在Python官網的Glossary第一次看到「duck typing」這個詞的時候,真的是很疑惑:Python怎麼會跟鴨子扯得上關係?更疑惑的是,那還是隻會打字的鴨子!
Thumbnail
小鴨子看起來笨笨的好可愛🦆 原來英文也有鴨子相關的片語 sitting duck不是指坐著的鴨子哦😂😂 先來跟朋友猜一下吧🤭 ⬇️⬇️⬇️看看下面的內容⬇️⬇️⬇️你就知道答案了
Thumbnail
小鴨子看起來笨笨的好可愛🦆 原來英文也有鴨子相關的片語 sitting duck不是指坐著的鴨子哦😂😂 先來跟朋友猜一下吧🤭 ⬇️⬇️⬇️看看下面的內容⬇️⬇️⬇️你就知道答案了
Thumbnail
大家都聽過的醜小鴨,用日文是怎麼講這個故事的呢? (影片3:20~6:45的部分) 什麼都不管,先來看醜小鴨。
Thumbnail
大家都聽過的醜小鴨,用日文是怎麼講這個故事的呢? (影片3:20~6:45的部分) 什麼都不管,先來看醜小鴨。
Thumbnail
大家都聽過的醜小鴨,用日文是怎麼講這個故事的呢? (本文著重於影片0:00~3:20的部分) 什麼都不管,先來看醜小鴨吧~
Thumbnail
大家都聽過的醜小鴨,用日文是怎麼講這個故事的呢? (本文著重於影片0:00~3:20的部分) 什麼都不管,先來看醜小鴨吧~
Thumbnail
鵝鴨總是分不清,找了一張鴨子小時候的照片,媽媽說「看腳掌」那是鵝。找了網路上分辨鵝鴨的文章,看原始照片的鼻孔位置,覺得那應該是鴨吧!但我畫得有點太偏中間了,哈哈。
Thumbnail
鵝鴨總是分不清,找了一張鴨子小時候的照片,媽媽說「看腳掌」那是鵝。找了網路上分辨鵝鴨的文章,看原始照片的鼻孔位置,覺得那應該是鴨吧!但我畫得有點太偏中間了,哈哈。
Thumbnail
鴨子的泰然自若似乎能給我們許多啟示。之前介紹過英文說要像水面上的鴨子(duck on water)一樣處變不驚,水面上悠哉地滑啊滑,水面下的腳丫子其實打水打得非常激烈。今天介紹的另一句英文也跟鴨子有關,我們要透過變裝皇后的實境秀節目來學它的意境。
Thumbnail
鴨子的泰然自若似乎能給我們許多啟示。之前介紹過英文說要像水面上的鴨子(duck on water)一樣處變不驚,水面上悠哉地滑啊滑,水面下的腳丫子其實打水打得非常激烈。今天介紹的另一句英文也跟鴨子有關,我們要透過變裝皇后的實境秀節目來學它的意境。
Thumbnail
鴨,俗稱鴨子,是對鴨科部分「屬」中的鳥類的通用名稱,其餘同屬鴨科但不稱作鴨的有天鵝、鵝、雁及鴛鴦等。
Thumbnail
鴨,俗稱鴨子,是對鴨科部分「屬」中的鳥類的通用名稱,其餘同屬鴨科但不稱作鴨的有天鵝、鵝、雁及鴛鴦等。
Thumbnail
當我們理所當然的看見鴨子或是兔子,我們對於自己腦海裡所既有的概念並不自覺。我們忽略了,人類在解讀任何外界訊息的時候,都並非是憑空的做出反應,而是不停地依據著自己曾經有過的經驗、概念或是相關的知識,相互比對而產生理解。
Thumbnail
當我們理所當然的看見鴨子或是兔子,我們對於自己腦海裡所既有的概念並不自覺。我們忽略了,人類在解讀任何外界訊息的時候,都並非是憑空的做出反應,而是不停地依據著自己曾經有過的經驗、概念或是相關的知識,相互比對而產生理解。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News