<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)型

          共 4392字,需瀏覽 9分鐘

           ·

          2021-05-02 08:51

          目錄

          • 1、什么是“鴨子類(lèi)型”

          • 2、“鴨子類(lèi)型”從何而來(lái)

            • 2.1 多態(tài)

            • 2.2 多態(tài)的使用

            • 2.3 鴨子類(lèi)型產(chǎn)生

          • 3、小結(jié)


          1、什么是“鴨子類(lèi)型”

          Python崇尚“鴨子類(lèi)型”

          對(duì)于鴨子類(lèi)型常見(jiàn)的說(shuō)法是:“當(dāng)看到一只鳥(niǎo)走起來(lái)像鴨子、游泳起來(lái)像鴨子、叫起來(lái)也像鴨子,那么這只鳥(niǎo)就可以被稱為鴨子。”

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

          在鴨子類(lèi)型中,關(guān)注點(diǎn)在于對(duì)象的行為能做什么;而不是關(guān)注對(duì)象所屬的類(lèi)型。例如,在不使用鴨子類(lèi)型的語(yǔ)言中,我們可以編寫(xiě)一個(gè)函數(shù),它接受一個(gè)類(lèi)型為"鴨子"的對(duì)象,并調(diào)用它的"走"和"叫"方法。在使用鴨子類(lèi)型的語(yǔ)言中,這樣的一個(gè)函數(shù)可以接受一個(gè)任意類(lèi)型的對(duì)象,并調(diào)用它的"走"和"叫"方法。如果這些需要被調(diào)用的方法不存在,那么將引發(fā)一個(gè)運(yùn)行時(shí)錯(cuò)誤。任何擁有這樣的正確的"走"和"叫"方法的對(duì)象都可被函數(shù)接受的這種行為引出了以上表述,這種決定類(lèi)型的方式因此得名

          鴨子類(lèi)型通常得益于"不"測(cè)試方法和函數(shù)中參數(shù)的類(lèi)型,而是依賴文檔、清晰的代碼和測(cè)試來(lái)確保正確使用

          在常規(guī)類(lèi)型中,我們能否在一個(gè)特定場(chǎng)景中使用某個(gè)對(duì)象取決于這個(gè)對(duì)象的類(lèi)型,而在鴨子類(lèi)型中,則取決于這個(gè)對(duì)象是否具有某種屬性或者方法——即只要具備特定的屬性或方法,能通過(guò)鴨子測(cè)試,就可以使用。

          內(nèi)容參考自維基百科:https://zh.wikipedia.org/wiki/%E9%B8%AD%E5%AD%90%E7%B1%BB%E5%9E%8B

          2、“鴨子類(lèi)型”從何而來(lái)

          2.1 多態(tài)

          先來(lái)看看“多態(tài)”

          大學(xué)時(shí)學(xué)習(xí)過(guò)CJava基礎(chǔ)這一類(lèi)強(qiáng)類(lèi)型語(yǔ)言,面向?qū)ο缶幊痰娜筇匦灾挥袀€(gè)概念叫做“多態(tài)”

          簡(jiǎn)單來(lái)說(shuō),定義時(shí)的類(lèi)型和運(yùn)行時(shí)的類(lèi)型不一樣就是多態(tài)

          更通俗的來(lái)說(shuō),多態(tài)是指一類(lèi)事物有多種形態(tài)。比如動(dòng)物有多種形態(tài),人、狗、貓等等

          放到二進(jìn)制的世界,例如文件,文件有多種形態(tài):文本文件、可執(zhí)行文件

          總而言之,多態(tài)即某類(lèi)的再分類(lèi),再分的每一類(lèi)就是父類(lèi)的多種形態(tài)的一種

          例如下面代碼示例:

          • 程序在運(yùn)行到list這一步是只把CatDogDuck當(dāng)成變量

          • 只有在最后實(shí)例化調(diào)用類(lèi)方法的時(shí)候才會(huì)明白是一個(gè)類(lèi),這就表示多態(tài)

          class Cat(object):
              def info(self):
                  print("我是一只貓")


          class Dog(object):
              def info(self):
                  print("我是一只狗")


          class Duck(object):
              def info(self):
                  print("我是一只鴨")

          list=[Cat,Dog,Duck]
          for animal in list:
              animal().info()

          2.2 多態(tài)的使用

          再來(lái)一個(gè)偏實(shí)際的應(yīng)用示例代碼

          from abc import ABCMeta,abstractmethod #(抽象方法)

          class Payment(metaclass=ABCMeta):   # metaclass 元類(lèi)  metaclass = ABCMeta表示Payment類(lèi)是一個(gè)規(guī)范類(lèi)
              def __init__(self,name,money):
                  self.money=money
                  self.name=name

              @abstractmethod      # @abstractmethod表示下面一行中的pay方法是一個(gè)必須在子類(lèi)中實(shí)現(xiàn)的方法
              def pay(self,*args,**kwargs):
                  pass

          class AliPay(Payment):

              def pay(self):
                  # 支付寶提供了一個(gè)網(wǎng)絡(luò)上的聯(lián)系渠道
                  print('%s通過(guò)支付寶消費(fèi)了%s元'%(self.name,self.money))

          class WeChatPay(Payment):

              def pay(self):
                  # 微信提供了一個(gè)網(wǎng)絡(luò)上的聯(lián)系渠道
                  print('%s通過(guò)微信消費(fèi)了%s元'%(self.name,self.money))


          class Order(object):

              def account(self,pay_obj):
                  pay_obj.pay()

          pay_obj = WeChatPay("wang",100)
          pay_obj2 = AliPay("zhang",200)

          order = Order()
          order.account(pay_obj)
          order.account(pay_obj2)

          從上述代碼可見(jiàn),在調(diào)用order對(duì)象的account()方法時(shí),程序并不關(guān)心為該方法傳入的參數(shù)對(duì)象pay_obj是誰(shuí),只要求此參數(shù)對(duì)象pay_obj包含pay()方法即可,而調(diào)用者傳入的參數(shù)對(duì)象類(lèi)型pay_obj是子類(lèi)對(duì)象還是其他類(lèi)對(duì)象,對(duì)Python來(lái)說(shuō)無(wú)所謂

          多態(tài)性就是相同的消息(函數(shù)方法觸發(fā))使得不同的類(lèi)做出不同的響應(yīng),這就是典型的類(lèi)編程中多態(tài)性的應(yīng)用實(shí)例

          2.3 鴨子類(lèi)型產(chǎn)生

          在上面的例子中order.account(pay_obj)pay_obj不需要類(lèi)型聲明,而java在使用時(shí)要定義好類(lèi)型

          order.account(Payment pay_obj)),所以你傳入別的類(lèi)型對(duì)象一定報(bào)錯(cuò)

          但是python因?yàn)槭莿?dòng)態(tài)語(yǔ)言所以傳入的對(duì)象只要擁有調(diào)用的方法即可視為Payment類(lèi)型對(duì)象,這就是所謂的鴨子類(lèi)型

          class Duck():
              def walk(self):
                  print('I walk like a duck')
              def swim(self):
                  print('i swim like a duck')

          class Person():
              def walk(self):
                print('this one walk like a duck'
              def swim(self):
                print('this man swim like a duck')

          可以很明顯的看出,Person類(lèi)擁有跟Duck類(lèi)一樣的方法,當(dāng)有一個(gè)函數(shù)調(diào)用Duck類(lèi),并利用到了兩個(gè)方法walk()swim()。我們傳入Person類(lèi)也一樣可以運(yùn)行,函數(shù)并不會(huì)檢查對(duì)象的類(lèi)型是不是Duck,只要他擁有walk()swim()方法,就可以正確的被調(diào)用

          3、小結(jié)

          • 在鴨子類(lèi)型中,關(guān)注的不是對(duì)象的類(lèi)型本身,而是它是如何使用的

          例如,在不使用鴨子類(lèi)型的語(yǔ)言中,我們可以編寫(xiě)一個(gè)函數(shù),它接受一個(gè)類(lèi)型為"鴨子"的對(duì)象,并調(diào)用它的"走"和"叫"方法

          • 在使用鴨子類(lèi)型的語(yǔ)言中,這樣的一個(gè)函數(shù)可以接受一個(gè)任意類(lèi)型的對(duì)象,并調(diào)用它的"走"和"叫"方法

          如果這些需要被調(diào)用的方法不存在,那么將引發(fā)一個(gè)運(yùn)行時(shí)錯(cuò)誤

          任何擁有這樣的正確的"走"和"叫"方法的對(duì)象都可被函數(shù)接受的這種行為引出了以上表述,這種決定類(lèi)型的方式因此得名

          • 鵝不是鴨子,但是鵝一旦擁有鴨子的一些方法,就可以被當(dāng)成鴨子類(lèi)型了

          • 鴨子類(lèi)型的好處就在于能夠避免一些類(lèi)的重寫(xiě),無(wú)需大量復(fù)制相同的代碼

          • 鴨子類(lèi)型使用的前提是需要良好的文檔支持,不然會(huì)讓代碼變得很混亂,如果沒(méi)有良好的文檔及說(shuō)明,有可能會(huì)導(dǎo)致你的“鴨子”不是我的“鵝”了

          瀏覽 54
          點(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>
                  视频在线a | 做爱视频网站免费看 | 操碰视频在线 | 亚洲欧美午夜人兽 | 最新在线无码热a |