鴨子打字

更新於 發佈於 閱讀時間約 9 分鐘
在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
15會員
132內容數
寫點東西自娛娛人
留言
avatar-img
留言分享你的想法!

































































ysf的沙龍 的其他內容
利用L-system畫出來的fractal圖案,最大的特色就是,橫看、豎看、左看、右看,全都一個樣,所以感覺總是不自然。就拿畫樹木來說吧,即便樹枝長度可以不一樣長,但是分岔的角度卻都一樣。所以囉,乍看之下,挺像一棵樹的,但仔細看的話,卻總覺得哪裡怪怪的,太人工化了。那怎麼讓它自然一些呢?
構成L-system的,是一串由符號所構成的字串。這字串裡頭的符號,可以是字母或者是任何喜歡的鬼畫符,想要用emoji也可以,只要你喜歡,沒什麼不可以。
一直以來都是靠手動的方式來進行檔案的版本管理,也就是自己複製檔案,然後改檔名,加入可以識別的編號。不過,越來越覺得,有必要用版本控制系統來幫忙,因為手動的方式實在很累人,而且當需要查找以前更動的內容時,非常沒有效率。當發現Spyder也有支援Git時,就想著:「好吧!那就試用看看好了。」
看到了一段程式碼,一段乍看之下覺得挺詭異,懷疑是不是寫錯,但搞清楚之後卻拍案叫絕,冷靜下來後卻覺得這樣寫不怎麼好的程式碼。
寫程式最怕碰到的,就是信心滿滿地寫好程式後,發現結果不如預期,而且完全看不出問題出在哪裡。這種慘況可以分成兩種:一種是程式很長、很複雜,想要把心機很重,躲在幽暗深處的臭蟲給抓出來,即使有功能強大的除錯工具,都不是件簡單的事;另一種是程式沒幾行,一切看起來都很清楚正常,臭蟲根本沒地方躲藏,可是結果就是
解決了Spyder和turtle之間的不合後,就來畫些漂亮迷人的fractal圖案,也順便練習一下recursive function的寫法。
利用L-system畫出來的fractal圖案,最大的特色就是,橫看、豎看、左看、右看,全都一個樣,所以感覺總是不自然。就拿畫樹木來說吧,即便樹枝長度可以不一樣長,但是分岔的角度卻都一樣。所以囉,乍看之下,挺像一棵樹的,但仔細看的話,卻總覺得哪裡怪怪的,太人工化了。那怎麼讓它自然一些呢?
構成L-system的,是一串由符號所構成的字串。這字串裡頭的符號,可以是字母或者是任何喜歡的鬼畫符,想要用emoji也可以,只要你喜歡,沒什麼不可以。
一直以來都是靠手動的方式來進行檔案的版本管理,也就是自己複製檔案,然後改檔名,加入可以識別的編號。不過,越來越覺得,有必要用版本控制系統來幫忙,因為手動的方式實在很累人,而且當需要查找以前更動的內容時,非常沒有效率。當發現Spyder也有支援Git時,就想著:「好吧!那就試用看看好了。」
看到了一段程式碼,一段乍看之下覺得挺詭異,懷疑是不是寫錯,但搞清楚之後卻拍案叫絕,冷靜下來後卻覺得這樣寫不怎麼好的程式碼。
寫程式最怕碰到的,就是信心滿滿地寫好程式後,發現結果不如預期,而且完全看不出問題出在哪裡。這種慘況可以分成兩種:一種是程式很長、很複雜,想要把心機很重,躲在幽暗深處的臭蟲給抓出來,即使有功能強大的除錯工具,都不是件簡單的事;另一種是程式沒幾行,一切看起來都很清楚正常,臭蟲根本沒地方躲藏,可是結果就是
解決了Spyder和turtle之間的不合後,就來畫些漂亮迷人的fractal圖案,也順便練習一下recursive function的寫法。
你可能也想看
Google News 追蹤
Thumbnail
還記得當年轟動一時,由李察·張伯倫主演的影集《幕府將軍》嗎?時隔40多年,這部描述日本戰國時代的史詩巨作再度登上螢幕,不同的是,新版《幕府將軍》大量使用日語對白,搭配英文字幕,在美國影視圈掀起了一股「字幕風潮」。 過去,美國觀眾普遍對字幕抱持抗拒心理,認為閱讀字幕會影響觀影體驗。然
蝌蚪叫鴨子教他游泳的方法, 鴨子說:「我不要!」 不死心的蝌蚪在1分鐘之內立刻流下2滴眼淚, 語帶哽咽:「求求你嘛!」 鴨子說:「你只要用蹼划一划就好啦!」 蝌蚪很努力,長出了像蹼的東西, ……………卻變成了青蛙………………
Thumbnail
本書從實際案例出發,提供溫和而有效的溝通技巧,幫助父母與孩子建立更深層的信任與連結。透過具體的操作方法,您將學會如何在日常對話中引導孩子表達內心想法,同時理解他們的情感需求,減少衝突與誤解。這不僅是一本溝通指南,更是一個能幫助家人共同成長的橋樑,讓孩子能夠更安心地與父母分享心事。
Thumbnail
八月的行事曆一片空白,除了座標是小琉球,以及來此的目的是咾咕嶼協會的海龜志工之外,其他都是未知。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
tzu在這個月踏上了學習之路,主要學習了Python、Azure服務和身份存取管理等領域,以及制定了短期目標。本文將分享她的學習進度和未來計劃。
Thumbnail
又稱橡皮鴨除錯法,是一種對於程式碼除錯(debug)的方法。
Thumbnail
上一週,我們已經學到了4組英語之中和鴨子(duck)相關的有趣片語,而在整理資料的過程之中,我意外地發現英語中和鴨子有關的有趣用法還真不少,所以今天我們仍要談一談另外一些和鴨子有淵源的有趣片語,也希望大家都能夠喜歡。
Thumbnail
還記得當年轟動一時,由李察·張伯倫主演的影集《幕府將軍》嗎?時隔40多年,這部描述日本戰國時代的史詩巨作再度登上螢幕,不同的是,新版《幕府將軍》大量使用日語對白,搭配英文字幕,在美國影視圈掀起了一股「字幕風潮」。 過去,美國觀眾普遍對字幕抱持抗拒心理,認為閱讀字幕會影響觀影體驗。然
蝌蚪叫鴨子教他游泳的方法, 鴨子說:「我不要!」 不死心的蝌蚪在1分鐘之內立刻流下2滴眼淚, 語帶哽咽:「求求你嘛!」 鴨子說:「你只要用蹼划一划就好啦!」 蝌蚪很努力,長出了像蹼的東西, ……………卻變成了青蛙………………
Thumbnail
本書從實際案例出發,提供溫和而有效的溝通技巧,幫助父母與孩子建立更深層的信任與連結。透過具體的操作方法,您將學會如何在日常對話中引導孩子表達內心想法,同時理解他們的情感需求,減少衝突與誤解。這不僅是一本溝通指南,更是一個能幫助家人共同成長的橋樑,讓孩子能夠更安心地與父母分享心事。
Thumbnail
八月的行事曆一片空白,除了座標是小琉球,以及來此的目的是咾咕嶼協會的海龜志工之外,其他都是未知。
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
tzu在這個月踏上了學習之路,主要學習了Python、Azure服務和身份存取管理等領域,以及制定了短期目標。本文將分享她的學習進度和未來計劃。
Thumbnail
又稱橡皮鴨除錯法,是一種對於程式碼除錯(debug)的方法。
Thumbnail
上一週,我們已經學到了4組英語之中和鴨子(duck)相關的有趣片語,而在整理資料的過程之中,我意外地發現英語中和鴨子有關的有趣用法還真不少,所以今天我們仍要談一談另外一些和鴨子有淵源的有趣片語,也希望大家都能夠喜歡。