<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          你知道什么是Python里的鴨子類(lèi)型和猴子補(bǔ)丁嗎?

          共 2163字,需瀏覽 5分鐘

           ·

          2021-10-14 15:49

          有時(shí)候我們會(huì)聽(tīng)到Python里所謂的鴨子類(lèi)型猴子補(bǔ)丁的說(shuō)法,乍一聽(tīng)還以為是來(lái)到了動(dòng)物園,Python這只大蟒蛇還可以和鴨子和猴子一起玩耍?


          非也非也,鴨子類(lèi)型和猴子補(bǔ)丁實(shí)際上是兩個(gè)生動(dòng)有趣的比喻,用來(lái)說(shuō)明Python的動(dòng)態(tài)特性。


          鴨子類(lèi)型??(duck type) 是對(duì)Python中數(shù)據(jù)類(lèi)型本質(zhì)上是由屬性和行為來(lái)定義的一種解讀。


          猴子補(bǔ)丁??(monkey patching)是對(duì)Python中類(lèi)和模塊可以在外部被動(dòng)態(tài)修改這種特性的一個(gè)比喻。


          讓我們來(lái)一探究竟吧!


          一,鴨子類(lèi)型

          鴨子類(lèi)型是對(duì)Python中數(shù)據(jù)類(lèi)型本質(zhì)上是由屬性和行為來(lái)定義的一種解讀。


          Python是一種動(dòng)態(tài)語(yǔ)言,不像Java和C++這種強(qiáng)類(lèi)型語(yǔ)言,Python里實(shí)際上沒(méi)有嚴(yán)格的類(lèi)型檢查。


          只要某個(gè)對(duì)象具有鴨子的方法,可以像鴨子那樣走路和嘎嘎叫,那么它就可以被其它函數(shù)當(dāng)做鴨子一樣調(diào)用。


          #?這是一個(gè)鴨子(Duck)類(lèi)
          class?Duck:
          ????def?__init__(self,name):
          ????????self.name?=?name
          ????def?swim(self):
          ????????print("A?duck?named?"?+?self.name+"?is?swimming...")
          ????def?call(self):
          ????????print("gay...gay...gay...")

          #?這是一個(gè)鵝(Goose)類(lèi)
          class?Goose:
          ????def?__init__(self,name):
          ????????self.name?=?name
          ????def?swim(self):
          ????????print("A?goose?named?"?+?self.name+"?is?swimming...")
          ????def?call(self):
          ????????print("goo...goo...goo...")

          # duckshow這個(gè)函數(shù)設(shè)計(jì)的本意是需要傳入一個(gè)Duck對(duì)象作為參數(shù)的。?
          def?duckshow(duck):
          ????duck.swim()
          ????duck.call()

          yaya?=?Duck("yaya")
          ee?=?Goose("ee")

          #?但由于Python是動(dòng)態(tài)語(yǔ)言,其數(shù)據(jù)類(lèi)型屬于鴨子類(lèi)型,沒(méi)有嚴(yán)格類(lèi)型檢查,
          #?Goose這個(gè)類(lèi)具有和Duck這個(gè)類(lèi)相同的方法,
          #?ee這只鵝劃起水來(lái)像只鴨子,叫起來(lái)也像一只鴨子,
          #?所以duckshow這個(gè)函數(shù)也可以對(duì)ee進(jìn)行作用。

          duckshow(yaya)
          duckshow(ee)

          輸出結(jié)果如下:
          A duck named yaya is swimming...gay ... gay ... gay ...A goose named ee is swimming...goo ... goo ... goo ...

          二,猴子補(bǔ)丁

          猴子補(bǔ)丁是對(duì)Python中模塊和類(lèi)可以在外部被動(dòng)態(tài)修改這種特性的一個(gè)比喻。


          為什么叫做猴子補(bǔ)丁呢?在模塊和類(lèi)的外部對(duì)模塊和類(lèi)進(jìn)行修改是一種非常耍賴(lài)的做法,會(huì)破壞代碼的封裝結(jié)構(gòu),這種事情大概只有淘氣的猴子喜歡去做,因此形象地稱(chēng)之為猴子補(bǔ)丁。


          #?定義一個(gè)Dog類(lèi)
          class?Dog:
          ????def?__init__(self,name,age):
          ????????self.name?=?name
          ????????self.age?=?age

          ????def?sleep(self):
          ????????print("Zzz...Zzz..Zzz...")

          #?在類(lèi)的外部給Dog這個(gè)類(lèi)添加猴子補(bǔ)丁
          def?speak(self):
          ????print("I?think?myself?a?hero?and?very?handsome!")

          Dog.speak?=?speak
          Dog.home?=?"Earth"

          #?與類(lèi)的內(nèi)部定義的屬性和方法無(wú)差異
          snoopy?=?Dog("snoopy",3)
          snoopy.sleep()
          snoopy.speak()
          print(snoopy.home)


          輸出結(jié)果如下:

          Zzz?...?Zzz?...?Zzz?...I think myself a hero and very handsome!Earth


          對(duì)于庫(kù)中已經(jīng)定義好的類(lèi),給它們添加猴子補(bǔ)丁有時(shí)候會(huì)非常方便,相當(dāng)于可以自由地在外面做擴(kuò)展,又不用修改源文件。


          import?numpy?as?np
          import?pandas?as?pd

          df?=?pd.DataFrame(np.random.randint(1,10,size=(5,5)),
          ??????????????????columns?=?list("abcde"))
          #df.info()
          #DataFrame自帶方法info打印信息太多,展示不直觀。
          #給DataFrame定義一個(gè)猴子補(bǔ)丁方法memory簡(jiǎn)潔展示其內(nèi)存消耗。

          def?memory(self):
          ????mem?=?self.__sizeof__()
          ????if?mem<1024:
          ????????return("%s?B"%mem)
          ????elif?mem<1024*1024:
          ????????return("%s?KB"%mem/1024)
          ????elif?mem<1024**3:
          ????????return("%s?MB"%mem/1024**2)
          ????else:
          ????????return("%s?GB"%mem/1024**3)?

          pd.DataFrame.memory?=?memory

          print(df.memory())


          輸出結(jié)果如下:

          280 B


          這就是Python里的鴨子類(lèi)型和猴子補(bǔ)丁的一個(gè)簡(jiǎn)單介紹,你耍明白了嗎?????????????


          瀏覽 39
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本无码每更新 | 日逼观看视频 | 国产操逼无码 | 黄片在现免费观看 | 91人妻人人澡人人爽人人精品 |