等等!python和鸭子是什么关系?
點擊上方“Python爬蟲與數據挖掘”,進行關注
回復“書籍”即可獲贈Python從入門到進階共10本電子書
今
日
雞
湯
窮則變,變則通,通則久。
眾所周知,python是一門編程語言,它可以做的東西很多,爬蟲、人工智能、自動化測試、數據分析等等。而鴨子是一種動物,它可以做的東西也很多,啤酒鴨、香烤鴨、鹽水鴨、土豆燜鴨等等。按理說這兩個對應著不同人體器官的東西應該是扯不上關系的。
但是,偏偏就有辣莫一個人,美國詩人詹姆斯·惠特科姆·萊利,在17世紀時寫下了一句詩:
「When I see a bird that walks like a duck and swims like a duck and quacks like a duck, I call that bird a duck.」
就是這短短的一句詩,讓這兩者扯上了神奇的關系,關鍵人們還為這種關系取了個名字 -- 鴨子類型。從此python和鴨子就成就了一段佳話啊呸,那這鴨子類型究竟是怎么回事呢?且往下看~
思考一個場景
加入在你擁有一款內容聚合應用,這款應用每天會從各個門戶網站采集一些文章回來,并且分發至應用里面的各個頻道。
這個時候我們可以將分發文章這個功能簡單的抽象為一個distribute函數,該函數由兩個參數構成,待分發文章article,分發頻道channel。
同時為了保證文章更符合頻道的內容范圍和調性,在每篇文章分發至頻道時,最好都對文章做一些準入校驗,于是我們初步封裝出以下函數:
def?distribute(article,?channel):#?文章準入判斷#?政務頻道的文章標題不能出現‘震驚’字眼if?channel.name?==?'politics'?and?article.title.find('震驚')?>=?0:return?False#?娛樂頻道不允許a,b這兩個作者的文章elif?channel.name?==?'entertainment'?and?article.author?in?['a','b']:return?False#?some?elif?here...#?將文章與頻道的綁定關系寫進數據庫return?bind_relation(article,?channel)上面的函數確實能夠實現我們想要的功能了,但是存在一個顯而易見的問題:如果我們每增加一條準入規則,就需要改動一次distribute函數,這樣頻繁地對一個函數動刀顯然不是一個好的做法。
我們希望這個函數是一個更抽象的公共函數,他不需要被過多的改動,于是我們做一點改進,變成下面的函數:
def?distribute(article,?channel):#?文章準入判斷can_push?=?channel.check(article)#?將文章與頻道的綁定關系寫進數據庫if?can_push:return?bind_relation(article,?channel)return?False將校驗頻道準入規則的這個功能用頻道類自己實現的check方法封裝起來,這樣每當有一個新的頻道需要創建,或者舊頻道需要更改校驗規則,則只需要負責維護各自頻道類的check方法就好了。
而distribute函數作為一個更高層級的存在則不會被影響到。
class?Article:def?__init__(self,?title,?author):self.title?=?titleself.author?=?authorclass?EntertainmentChannel:def?__init__(self)self.name?=?'entertainment'def?check(article):if?article.author?in?['a','b']:return?Falsereturn?Trueclass?PoliticsChannel:def?__init__(self)self.name?=?'politics'def?check(article):if?article.title.find('震驚')?>=?0:return?Falsereturn?Truearitcle_a?=?Article('震驚!大笑1小時壽命減少60分鐘!',?'a') aritcle_b?=?Article('戰勝恐懼最好的辦法?',?'b')politics_channel?=?PoliticsChannel() entertainment_channel?=?EntertainmentChannel()distribute(aritcle_a,?politics_channel)??#?Fasle distribute(aritcle_b,?entertainment_channel)??#?Fasle多態
上面對于distribute函數的改造結果,其實很類似于面向對象三大特征之一 —— 多態 的應用。
簡單解釋起來,多態就是同一操作(方法)被作用于不同的對象時,可以有不同的解釋,產生不同的執行結果。
例如上面的check方法,當它由EntertainmentChannel類實例調用時,檢查的是文章標題不能包含“震驚”字眼;由PoliticsChannel類實例調用時,檢查的是文章作者不能是’a'和‘b’。
多態在靜態語言如 Java 中,通常通過子類繼承父類,然后子類重寫父類中的某些方法來實現多態。但是在python中,不需要搞子承父業這一套,只需要在不同的類里面實現好名字相同的方法,即可在運行時表現出多態。
只不過,這種特征在python中一般不叫多態,而是我們前面提到的——鴨子類型。
鴨子類型
鴨子類型的名字來源和具體應用場景前面已經描述過了,而關于鴨子類型的定義,網上出現最多的就是對文章開頭那句英文詩句的翻譯:
如果一只鳥走起來像鴨子,發出的聲音像鴨子,游起來像鴨子,那么它就是一只鴨子
這句話重點在于引導我們只關注事物的行為,而不是關注事物本身和它的表現。再看一個幫助理解的栗子????:
class?Duck:def?sound(self):print('quack')def?walk(self):print('da?da?da')class?Dog:def?sound(self):print('wang')def?walk(self):print('tita?tita?tita')def?walk_and_sound(animal):animal.walk()animal.sound()dog?=?Dog() duck?=?Duck()walk_and_sound(dog)?#?tita?tita?tita?wang walk_and_sound(duck)?#?da?da?da?quack就好像一只狗會走,會叫;鴨子也會走,會叫。狗有很多行為都跟鴨子相似,他們做的動作是一樣的,只是表現出來不一樣。
我們關注的是類有什么方法,能做什么,而不是類是怎么定義的,表現出來是怎么樣的。這個正是鴨子類型想表達的思想。
總結
鴨子類型是python中多態的一種實現方式。
鴨子類型強調關注事物的行為而不是事物本身和事物的表現,如果某些類都實現了同名方法,那這些類就符合鴨子類型。
后記&引用
其實我仔細想了想,如果我早出生幾個世紀,在詹姆斯·惠特科姆·萊利寫出那句詩之前,喊出 「如果一個四肢動物走起來像狗,叫起來像狗,傻起來像狗,那它就是一只狗」~這樣一句話。
是不是現在就不叫鴨子類型而改叫狗子類型呢?唉,又錯過了名留千史的機會,還是應了一句老話:出名要趁早啊!
-------------------?End?-------------------
往期精彩文章推薦:
Python環境搭建—安利Python小白的Python和Pycharm安裝詳細教程
一篇文章教會你理解Scrapy網絡爬蟲框架的工作原理和數據采集過程
利用Python網絡爬蟲抓取微信好友的簽名及其可視化展示
歡迎大家點贊,留言,轉發,轉載,感謝大家的相伴與支持
想加入Python學習群請在后臺回復【入群】
萬水千山總是情,點個【在看】行不行
/今日留言主題/
隨便說一兩句吧~~
總結
以上是生活随笔為你收集整理的等等!python和鸭子是什么关系?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据结构练习题【哈夫曼树、图、排序、散列
- 下一篇: Kafka面试专题