最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

簡單聊聊Python中的鴨子類型和猴子補(bǔ)丁

 更新時(shí)間:2022年04月12日 07:45:16   作者:yongxinz  
不知不覺使用python寫代碼已經(jīng)很長時(shí)間了,下面這篇文章主要給大家介紹了關(guān)于python鴨子類型(duck?type)和猴子補(bǔ)丁(mokey?patching)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

Python 開發(fā)者可能都聽說過鴨子類型和猴子補(bǔ)丁這兩個(gè)詞,即使沒聽過,也大概率寫過相關(guān)的代碼,只不過并不了解其背后的技術(shù)要點(diǎn)是這兩個(gè)詞而已。

我最近在面試候選人的時(shí)候,也會(huì)問這兩個(gè)概念,很多人答的也并不是很好。但是當(dāng)我向他們解釋完之后,普遍都會(huì)恍然大悟:“哦,是這個(gè)啊,我用過”。

所以,我決定來寫一篇文章,探討一下這兩個(gè)技術(shù)。

鴨子類型

引用維基百科中的一段解釋:

鴨子類型(duck typing)在程序設(shè)計(jì)中是動(dòng)態(tài)類型的一種風(fēng)格。在這種風(fēng)格中,一個(gè)對(duì)象有效的語義,不是由繼承自特定的類或?qū)崿F(xiàn)特定的接口,而是由"當(dāng)前方法和屬性的集合"決定。

更通俗一點(diǎn)的說:

當(dāng)看到一只鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那么這只鳥就可以被稱為鴨子。

也就是說,在鴨子類型中,關(guān)注點(diǎn)在于對(duì)象的行為,能作什么;而不是關(guān)注對(duì)象所屬的類型。

我們看一個(gè)例子,更形象地展示一下:

# 這是一個(gè)鴨子(Duck)類
class Duck:
? ? def eat(self):
? ? ? ? print("A duck is eating...")

? ? def walk(self):
? ? ? ? print("A duck is walking...")


# 這是一個(gè)狗(Dog)類
class Dog:
? ? def eat(self):
? ? ? ? print("A dog is eating...")

? ? def walk(self):
? ? ? ? print("A dog is walking...")


def animal(obj):
? ? obj.eat()
? ? obj.walk()


if __name__ == '__main__':
? ? animal(Duck())
? ? animal(Dog())

程序輸出:

A duck is eating...
A duck is walking...
A dog is eating...
A dog is walking...

Python 是一門動(dòng)態(tài)語言,沒有嚴(yán)格的類型檢查。只要 Duck 和 Dog 分別實(shí)現(xiàn)了 eat 和 walk 方法就可以直接調(diào)用。

再比如 list.extend() 方法,除了 list 之外,dict 和 tuple 也可以調(diào)用,只要它是可迭代的就都可以調(diào)用。

看過上例之后,應(yīng)該對(duì)「對(duì)象的行為」和「對(duì)象所屬的類型」有更深的體會(huì)了吧。

再擴(kuò)展一點(diǎn),其實(shí)鴨子類型和接口挺像的,只不過沒有顯式定義任何接口。

比如用 Go 語言來實(shí)現(xiàn)鴨子類型,代碼是這樣的:

package main

import "fmt"

// 定義接口,包含 Eat 方法
type Duck interface {
?Eat()
}

// 定義 Cat 結(jié)構(gòu)體,并實(shí)現(xiàn) Eat 方法
type Cat struct{}

func (c *Cat) Eat() {
?fmt.Println("cat eat")
}

// 定義 Dog 結(jié)構(gòu)體,并實(shí)現(xiàn) Eat 方法
type Dog struct{}

func (d *Dog) Eat() {
?fmt.Println("dog eat")
}

func main() {
?var c Duck = &Cat{}
?c.Eat()

?var d Duck = &Dog{}
?d.Eat()

?s := []Duck{
? &Cat{},
? &Dog{},
?}
?for _, n := range s {
? n.Eat()
?}
}

通過顯式定義一個(gè) Duck 接口,每個(gè)結(jié)構(gòu)體實(shí)現(xiàn)接口中的方法來實(shí)現(xiàn)。

猴子補(bǔ)丁

猴子補(bǔ)?。∕onkey Patch)的名聲不太好,因?yàn)樗鼤?huì)在運(yùn)行時(shí)動(dòng)態(tài)修改模塊、類或函數(shù),通常是添加功能或修正缺陷。

猴子補(bǔ)丁在內(nèi)存中發(fā)揮作用,不會(huì)修改源碼,因此只對(duì)當(dāng)前運(yùn)行的程序?qū)嵗行А?/p>

但如果濫用的話,會(huì)導(dǎo)致系統(tǒng)難以理解和維護(hù)。

主要有兩個(gè)問題:

  • 補(bǔ)丁會(huì)破壞封裝,通常與目標(biāo)緊密耦合,因此很脆弱
  • 打了補(bǔ)丁的兩個(gè)庫可能相互牽絆,因?yàn)榈诙€(gè)庫可能會(huì)撤銷第一個(gè)庫的補(bǔ)丁

所以,它被視為臨時(shí)的變通方案,不是集成代碼的推薦方式。

按照慣例,還是舉個(gè)例子來說明:

# 定義一個(gè)Dog類
class Dog:
? ? def eat(self):
? ? ? ? print("A dog is eating ...")

# 在類的外部給 Dog 類添加猴子補(bǔ)丁
def walk(self):
? ? print("A dog is walking ...")

Dog.walk = walk

# 調(diào)用方式與類的內(nèi)部定義的屬性和方法一樣
dog = Dog()
dog.eat()
dog.walk()

程序輸出:

A dog is eating ...
A dog is walking ...

這里相當(dāng)于在類的外部給 Dog 類增加了一個(gè) walk 方法,而調(diào)用方式與類的內(nèi)部定義的屬性和方法一樣。

再舉一個(gè)比較實(shí)用的例子,比如我們常用的 json 標(biāo)準(zhǔn)庫,如果說想用性能更高的 ujson 代替的話,那勢必需要將每個(gè)文件的引入:

import json

改成:

import ujson as json

如果這樣改起來成本就比較高了。這個(gè)時(shí)候就可以考慮使用猴子補(bǔ)丁,只需要在程序入口加上:

import json ?
import ujson ?

def monkey_patch_json(): ?
? ? json.__name__ = 'ujson' ?
? ? json.dumps = ujson.dumps ?
? ? json.loads = ujson.loads ?

monkey_patch_json()

這樣在以后調(diào)用 dumps 和 loads 方法的時(shí)候就是調(diào)用的 ujson 包,還是很方便的。

但猴子補(bǔ)丁就是一把雙刃劍,問題也在上文中提到了,看需,謹(jǐn)慎使用吧。

總結(jié)

到此這篇關(guān)于Python中鴨子類型和猴子補(bǔ)丁的文章就介紹到這了,更多相關(guān)Python鴨子類型和猴子補(bǔ)丁內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python實(shí)用技巧之列表、字典、集合中根據(jù)條件篩選數(shù)據(jù)詳解

    Python實(shí)用技巧之列表、字典、集合中根據(jù)條件篩選數(shù)據(jù)詳解

    這篇文章主要給大家介紹了關(guān)于Python技巧之在列表、字典、集合中根據(jù)條件篩選數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧
    2018-07-07
  • python BeautifulSoup設(shè)置頁面編碼的方法

    python BeautifulSoup設(shè)置頁面編碼的方法

    這篇文章主要介紹了python BeautifulSoup設(shè)置頁頁編碼的方法,本文直接給出代碼救命,需要的朋友可以參考下
    2015-04-04
  • Python進(jìn)度條可視化之監(jiān)測程序運(yùn)行速度

    Python進(jìn)度條可視化之監(jiān)測程序運(yùn)行速度

    Tqdm是一個(gè)快速,可擴(kuò)展的Python進(jìn)度條,可以在Python長循環(huán)中添加一個(gè)進(jìn)度提示信息,用戶只需要封裝任意的迭代器即可。本文就主要介紹了通過進(jìn)度條檢測程序運(yùn)行速度,感興趣的同學(xué)可以學(xué)習(xí)一下
    2021-12-12
  • python df遍歷的N種方式(小結(jié))

    python df遍歷的N種方式(小結(jié))

    本文主要介紹了python df遍歷的N種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • python保留小數(shù)位的三種實(shí)現(xiàn)方法

    python保留小數(shù)位的三種實(shí)現(xiàn)方法

    本文給大家分享python保留小數(shù)位的三種方法,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 基于Python實(shí)現(xiàn)png轉(zhuǎn)webp的命令行工具

    基于Python實(shí)現(xiàn)png轉(zhuǎn)webp的命令行工具

    網(wǎng)頁上使用webp格式的圖片更加省網(wǎng)絡(luò)流量和存儲(chǔ)空間,但本地圖片一般是png格式的,所以本文就來為大家介紹一下如何使用Python實(shí)現(xiàn)png轉(zhuǎn)webp功能吧
    2025-02-02
  • 對(duì)python數(shù)據(jù)切割歸并算法的實(shí)例講解

    對(duì)python數(shù)據(jù)切割歸并算法的實(shí)例講解

    今天小編就為大家分享一篇對(duì)python數(shù)據(jù)切割歸并算法的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-12-12
  • python?tkinter庫的Text記錄點(diǎn)擊路經(jīng)和刪除記錄詳情

    python?tkinter庫的Text記錄點(diǎn)擊路經(jīng)和刪除記錄詳情

    這篇文章主要介紹了python?tkinter庫的Text記錄點(diǎn)擊路經(jīng)和刪除記錄詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-06-06
  • python PrettyTable模塊的安裝與簡單應(yīng)用

    python PrettyTable模塊的安裝與簡單應(yīng)用

    prettyTable 是一款很簡潔但是功能強(qiáng)大的第三方模塊,主要是將輸入的數(shù)據(jù)轉(zhuǎn)化為格式化的形式來輸出,這篇文章主要介紹了python PrettyTable模塊的安裝與簡單應(yīng)用,感興趣的小伙伴們可以參考一下
    2019-01-01
  • PyChon中關(guān)于Jekins的詳細(xì)安裝(推薦)

    PyChon中關(guān)于Jekins的詳細(xì)安裝(推薦)

    這篇文章主要介紹了PyChon中關(guān)于Jekins的詳細(xì)安裝(推薦),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12

最新評(píng)論

米脂县| 宣恩县| 安岳县| 永福县| 临潭县| 拉孜县| 长武县| 鸡西市| 宁陕县| 东海县| 罗山县| 自治县| 含山县| 柯坪县| 巴彦淖尔市| 高邮市| 济南市| 保德县| 安福县| 中山市| 泗水县| 公安县| 胶州市| 义乌市| 锡林浩特市| 汝南县| 溆浦县| 甘孜| 雷山县| 昌宁县| 揭东县| 连江县| 西青区| 武乡县| 丰都县| 邮箱| 启东市| 铅山县| 金川县| 安西县| 黔南|