鴨子打字

更新於 發佈於 閱讀時間約 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會員
131內容數
寫點東西自娛娛人
留言0
查看全部
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
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
tzu在這個月踏上了學習之路,主要學習了Python、Azure服務和身份存取管理等領域,以及制定了短期目標。本文將分享她的學習進度和未來計劃。
Thumbnail
又稱橡皮鴨除錯法,是一種對於程式碼除錯(debug)的方法。
Thumbnail
上一週,我們已經學到了4組英語之中和鴨子(duck)相關的有趣片語,而在整理資料的過程之中,我意外地發現英語中和鴨子有關的有趣用法還真不少,所以今天我們仍要談一談另外一些和鴨子有淵源的有趣片語,也希望大家都能夠喜歡。
Thumbnail
在使用類別創建實例時,輸入的屬性的都要定義好資料型態,例如dog_1 = Dog("Buddy", 3),有沒有輸入一段字串讓他自己判斷的方法阿? 有的就是使用classmethod: classmethod 是一種裝飾器,它用於定義類別方法。類別方法與實例方法不同,它們被綁定到類別而不是實例。
Thumbnail
在人與人溝通之間,最怕雞同鴨講,彼此不對頻的狀況常會造成誤會。在程式語言中也會出現類似的情況,所以就有一些約定來彼此約束。 PEP 8 是 Python 社群廣泛遵循的一種風格指南,用於提高 Python 程式碼的可讀性和一致性。一開始是 Python 之父 Guido van Rossum 自己
Thumbnail
本文介紹了Python中函式引數的*args和**kwargs用法,通過*args處理可變數量的位置引數,通過**kwargs處理可變數量的關鍵字引數。不僅介紹了相應的語法和程式範例,還解釋了它們的順序問題和建議的慣例用法。
Thumbnail
宣告變數 變數是程式中用來儲存和表示數據的標識符號​,並將變數存放在某個記憶體位子 可以用ID的方法查找變數存在哪個記憶體,此方法有利於以後查找問題用。 在大多數程式語言中,變數需要事先聲明(宣告)並賦值。 而Python是一種動態類型語言,不需要顯式宣告變數類型,而是在賦值時自動進行推斷。
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,
Thumbnail
隨著理財資訊的普及,越來越多台灣人不再將資產侷限於台股,而是將視野拓展到國際市場。特別是美國市場,其豐富的理財選擇,讓不少人開始思考將資金配置於海外市場的可能性。 然而,要參與美國市場並不只是盲目跟隨標的這麼簡單,而是需要策略和方式,尤其對新手而言,除了選股以外還會遇到語言、開戶流程、Ap
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本文介紹了Python中的物件導向程式設計的重要概念,包括類別、繼承、多型、封裝、介面、抽象類別、靜態類別、列舉、委派、Lambda表達式、泛型和反射。每個概念都有對應的程式碼範例來說明其用法和功能。這些概念對於理解和使用Python進行物件導向程式設計至關重要。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
tzu在這個月踏上了學習之路,主要學習了Python、Azure服務和身份存取管理等領域,以及制定了短期目標。本文將分享她的學習進度和未來計劃。
Thumbnail
又稱橡皮鴨除錯法,是一種對於程式碼除錯(debug)的方法。
Thumbnail
上一週,我們已經學到了4組英語之中和鴨子(duck)相關的有趣片語,而在整理資料的過程之中,我意外地發現英語中和鴨子有關的有趣用法還真不少,所以今天我們仍要談一談另外一些和鴨子有淵源的有趣片語,也希望大家都能夠喜歡。
Thumbnail
在使用類別創建實例時,輸入的屬性的都要定義好資料型態,例如dog_1 = Dog("Buddy", 3),有沒有輸入一段字串讓他自己判斷的方法阿? 有的就是使用classmethod: classmethod 是一種裝飾器,它用於定義類別方法。類別方法與實例方法不同,它們被綁定到類別而不是實例。
Thumbnail
在人與人溝通之間,最怕雞同鴨講,彼此不對頻的狀況常會造成誤會。在程式語言中也會出現類似的情況,所以就有一些約定來彼此約束。 PEP 8 是 Python 社群廣泛遵循的一種風格指南,用於提高 Python 程式碼的可讀性和一致性。一開始是 Python 之父 Guido van Rossum 自己
Thumbnail
本文介紹了Python中函式引數的*args和**kwargs用法,通過*args處理可變數量的位置引數,通過**kwargs處理可變數量的關鍵字引數。不僅介紹了相應的語法和程式範例,還解釋了它們的順序問題和建議的慣例用法。
Thumbnail
宣告變數 變數是程式中用來儲存和表示數據的標識符號​,並將變數存放在某個記憶體位子 可以用ID的方法查找變數存在哪個記憶體,此方法有利於以後查找問題用。 在大多數程式語言中,變數需要事先聲明(宣告)並賦值。 而Python是一種動態類型語言,不需要顯式宣告變數類型,而是在賦值時自動進行推斷。
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,