欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

PythonI/O進(jìn)階學(xué)習(xí)筆記_3.2面向?qū)ο缶幊蘝python的繼承(多繼承

系統(tǒng) 2126 0

前言:

本篇相關(guān)內(nèi)容分為3篇多態(tài)、繼承、封裝,這篇為第二篇 繼承。

本篇內(nèi)容圍繞 python基礎(chǔ)教程這段:
在面向?qū)ο缶幊讨校g(shù)語對象大致意味著一系列數(shù)據(jù)(屬性)以及一套訪問和操作這些數(shù)據(jù)的方法。使用對象而非全局變量和函數(shù)的原因有多個,下面列出了使用對象的最重要的好處。
? 多態(tài):可對不同類型的對象執(zhí)行相同的操作,而這些操作就像“被施了魔法”一樣能夠正常運行。
? 封裝:對外部隱藏有關(guān)對象工作原理的細(xì)節(jié)。
? 繼承:可基于通用類創(chuàng)建出專用類。
內(nèi)容較多,這篇為中篇。

Content:

- 繼承

1. 什么是繼承,繼承的作用和常用狀態(tài)?

2. python的多繼承、instance和type?

3. python中的super函數(shù)

4. python的MRO查找機(jī)制來對應(yīng)多繼承和super

5. python的抽象基類

6. django等大大框架和python源碼中最常用的Mixin模式多繼承實例

?(下篇

- 封裝

1.數(shù)據(jù)封裝和私有屬性

2. 類變量和實例變量(對象變量)

3. 類屬性和實例屬性得查找順序(MRO)

4. 靜態(tài)方法 類方法和對象方法使用以及參數(shù)

5. python的接口和自省機(jī)制

6. 上下文管理器

?)

?

一 繼承

1.什么是繼承?繼承有哪些作用?常用?

? ? - 繼承的概念? :在OOP程序設(shè)計中,當(dāng)我們定義一個class的時候,可以從某個現(xiàn)有的class繼承,新的class稱為子類(Subclass),而被繼承的class稱為基類、父類或超類(Base class、Super class)。

            
              //INPUT:
              
class
Animals(): def say(self): print ( " say something " ) def eat(self): print ( " eat something " ) class Duck(Animals): def say(self): print ( " gaga " ) class Dog(Animals): def say(self): print ( " wangwang " ) class Miao(Animals): def say(self): print ( " miaomiao " ) for i in [Duck(),Dog(),Miao()]: i.eat()

//OUTPUY:
eat something
eat something
eat something

? ? - 繼承的作用:可以解決代碼重用的問題。

? ? - 比較常用的應(yīng)該就是在python相關(guān)web框架里這種比較比較復(fù)雜的框架,和許多第三方庫的類。天知道這些大牛的框架里面默默有效率的幫我們做了多少事- -。天知道我們直接用他們的方法有多方便。

?

2.python多繼承需要注意哪些?用instance和type來判斷python類繼承的關(guān)系。

a.多繼承需要注意的地方:

- 類繼承的順序和方法在多繼承類中查找的順序

? ? --.子類繼承父類時,在子類進(jìn)行屬性調(diào)用的順序為:先查找自己的屬性字典,若自己的屬性字典中無該屬性,則會依次按照繼承父類的順序來依次查找父類的屬性字典;

? ? --.子類繼承父類,當(dāng)父類和子類均有相同的屬性時,子類并不會影響父類的屬性。

總結(jié)起來就是: 按繼承的順序來依次查詢屬性,一旦查到則停止;子類和父類的屬性相互獨立,互不影響;子類可以調(diào)用父類的屬性,反之不行

b.用instance和type來判斷兩個類的關(guān)系

instance和type都是用來判斷參數(shù)1是否是參數(shù)2類型,區(qū)別在于是否會考慮繼承關(guān)系。

isinstance:
?
type:
type(b)是:
由上可得,type用于判斷對象,而isinstance判斷是否在繼承鏈里面。
?
3.python的super函數(shù)
a.super函數(shù)干嘛的?為什么要用super?
實際上是用來調(diào)用自己的父類的。
super 是用來解決多重繼承問題的,直接用類名調(diào)用父類方法在使用單繼承的時候沒問題,但是如果使用多繼承,會涉及到查找順序(MRO)、重復(fù)調(diào)用(鉆石繼承)等種種問題。MRO 就是類的方法解析順序表, 其實也就是繼承父類方法時的順序表。
?
b.super的用法
在python2中,super(B,self).__init__()
python3中 super().__init__()
                
                  #
                
                
                  Python3.x 實例:
                
                
                  class
                
                
                   A:
     
                
                
                  def
                
                
                   add(self, x):
         y 
                
                = x+1
         
                
                  print
                
                
                  (y)

                
                
                  class
                
                
                   B(A):
    
                
                
                  def
                
                
                   add(self, x):
        super().add(x)
b 
                
                =
                
                   B()
b.add(
                
                2)  
                
                  #
                
                
                   3
                
                
# Python2.x 實例: # !/usr/bin/python # -*- coding: UTF-8 -*- class A(object): # Python2.x 記得繼承 object def add(self, x): y = x+1 print (y) class B(A): def add(self, x): super(B, self).add(x) b = B() b.add( 2) # 3

?

4.super和多繼承時查找父類的順序 MRO C3算法
a.MRO C3算法

C3線性是用于獲取多重繼承下繼承順序的一種算法。通常,被稱為 方法解析順序 ,即MRO(method resolution order)。

算法的名字“C3”并不是縮寫,而是指該算法的三大重要屬性:

- 前趨圖。作為有向無環(huán)圖,找不到任何的循環(huán),通常用前趨圖來理解程序的依賴關(guān)系。

- 保持局部的優(yōu)先次序。

- 單調(diào)性。

C3是1996年首次被提出。在python2.3及后續(xù)版本中,C3被選定為默認(rèn)的解析算法。

一個類的C3線性表,是由兩部分進(jìn)行merge操作得到的,第一部分是是它所有父類的C3線性表(parents' linearizations),第二部分是它所有父類組成的列表(parents list)。后者其實是局部的優(yōu)先級列表。

在C3被應(yīng)用之前,廣度優(yōu)先和深度優(yōu)先是被應(yīng)用于解析順序的。

C3算法計算方法:有點類似拓?fù)渑判颍ㄓ邢驁D) ? ? ?想深刻了解 C3 還是自己查吧...下面有段簡單的多繼承代碼和其對應(yīng)的拓?fù)渑判虻某橄髨D ( 所用代碼實例和圖片均來應(yīng)用自別處,文章末尾有鏈接 )

                  
                    class
                  
                  
                     D(object):
    
                  
                  
                    pass
                  
                  
                    class
                  
                  
                     E(object):
    
                  
                  
                    pass
                  
                  
                    class
                  
                  
                     F(object):
    
                  
                  
                    pass
                  
                  
                    class
                  
                  
                     C(D, F):
    
                  
                  
                    pass
                  
                  
                    class
                  
                  
                     B(E, D):
    
                  
                  
                    pass
                  
                  
                    class
                  
                  
                     A(B, C):
    
                  
                  
                    pass
                  
                  
                    if
                  
                  
                    __name__
                  
                   == 
                  
                    '
                  
                  
                    __main__
                  
                  
                    '
                  
                  
                    :
    
                  
                  
                    print
                  
                   A.
                  
                    __mro__
                  
                

得到的輸出結(jié)果:

                  (<
                  
                    class
                  
                  
                    '
                  
                  
                    __main__.A
                  
                  
                    '
                  
                  >, <
                  
                    class
                  
                  
                    '
                  
                  
                    __main__.B
                  
                  
                    '
                  
                  >, <
                  
                    class
                  
                  
                    '
                  
                  
                    __main__.E
                  
                  
                    '
                  
                  >, <
                  
                    class
                  
                  
                    '
                  
                  
                    __main__.C
                  
                  
                    '
                  
                  >, <
                  
                    class
                  
                  
                    '
                  
                  
                    __main__.D
                  
                  
                    '
                  
                  >, <
                  
                    class
                  
                  
                    '
                  
                  
                    __main__.F
                  
                  
                    '
                  
                  >, 
                  
                    
                      '
                    
                    
                      object
                    
                    
                      '
                    
                    >)
                  
                
  • 下面就是抽象出來的圖


我們就用拓?fù)渑判騺矸治觯沁@里會碰到同時存在好幾個點都是入度為0 (說人話,就是沒有被別人指向的點),這時按照樹的排序來,即 從左到右,從根到葉 ,這里 A 就是根。

所以具體情況就是:我們先找到了點 A只有它沒有被別人指向,輸出 A ;去掉A及其伸出的兩條線,剩 B 和 C 點同時滿足只指向別人,按照樹的順序從左到右,故先輸出 B ;去掉線剩 E 和 C ,輸出 E ;去線剩 C,輸出 C ;去線剩 D 和 F ,輸出 D ;去線只剩F ,輸出 F ;最后輸出 object ;得到的輸出結(jié)果:? A B E C D F object

對比系統(tǒng)打印出的結(jié)果,順序是一致的。這樣下次你就可以裝逼地手動計算多繼承時調(diào)用類的順序了


以上結(jié)論來源鏈接:https://www.jianshu.com/p/6651ed35104c

b.用__init__和超類的super().__init__看子類和父類的構(gòu)造函數(shù)關(guān)系。
現(xiàn)在有一個繼承關(guān)系,SonBird繼承Bird。但是子類和父類都有自己的構(gòu)造函數(shù)。
              
                class
              
              
                 Bird:
    
              
              
                def
              
              
                __init__
              
              
                (self):
          self.hungry 
              
              =
              
                 True
    
              
              
                def
              
              
                 eat(self):
          
              
              
                if
              
              
                 self.hungry:
               
              
              
                print
              
              
                '
              
              
                Ahahahah
              
              
                '
              
              
                else
              
              
                :
               
              
              
                print
              
              
                '
              
              
                No thanks!
              
              
                '
              
              
                class
              
              
                 SongBird(Bird):
     
              
              
                def
              
              
                __init__
              
              
                (self):
          self.sound 
              
              = 
              
                '
              
              
                Squawk
              
              
                '
              
              
                def
              
              
                 sing(self):
          
              
              
                print
              
              
                 self.song()

sb 
              
              =
              
                 SongBird()
sb.sing()    
              
              
                #
              
              
                 能正常輸出
              
              
sb.eat()     
              
                #
              
              
                 報錯,因為 songgird 中沒有 hungry 特性
              
            

這時候,如果需要繼承父類構(gòu)造函數(shù)里的屬性,其實是可以有兩種方法的。

第一種 - 調(diào)用未綁定的超類構(gòu)造方法(多用于舊版 python 陣營)

              
                class
              
              
                 SongBird(Bird):
     
              
              
                def
              
              
                __init__
              
              
                (self):
          Bird.
              
              
                __init__
              
              
                (self)
          self.sound 
              
              = 
              
                '
              
              
                Squawk
              
              
                '
              
              
                def
              
              
                 sing(self):
          
              
              
                print
              
               self.song()
            

原理 :在調(diào)用了一個實例的方法時,該方法的self參數(shù)會自動綁定到實例上(稱為綁定方法);如果直接調(diào)用類的方法(比如Bird.__init__),那么就沒有實例會被綁定,可以自由提供需要的self參數(shù)(未綁定方法)。

第二種 - 使用super函數(shù)(只在新式類中有用)

              
                class
              
              
                 SongBird(Bird):
     
              
              
                def
              
              
                __init__
              
              
                (self):
          super(SongBird,self).
              
              
                __init__
              
              
                ()
          self.sound 
              
              = 
              
                '
              
              
                Squawk
              
              
                '
              
              
                def
              
              
                 sing(self):
          
              
              
                print
              
               self.song()
            

原理: 它會查找所有的超類,以及超類的超類,直到找到所需的特性為止。

?
5.python的抽象基類(abc)
a.什么是抽象基類? 抽象基類的特性?
  抽象基類的作用類似于JAVA中的接口。在接口中定義各種方法,然后繼承接口的各種類進(jìn)行具體方法的實現(xiàn)。抽象基類就是定義各種方法而不做具體實現(xiàn)的類,任何繼承自抽象基類的類必須實現(xiàn)這些方法,否則無法實例化。
抽象基類的特性:
- 無法用來實例化。
?
?
b.為什么要有抽象基類?直接用鴨子類型不就好了?
第一個需求:在某些情況下,我們需要判定某個對象的類型。
第二個需求:我們需要強(qiáng)制某個子類必須實現(xiàn)某些方法
?
c.抽象基類的應(yīng)用
抽象類是不能(至少是不應(yīng)該)實例化的類,其職責(zé)是定義子類應(yīng)實現(xiàn)的一組抽象方法。
下面是一個簡單的示例:使用@abstractmethod來將方法標(biāo)記為抽象的——在子類中必須實現(xiàn)的方法。
              
                from
              
               abc 
              
                import
              
              
                 ABC, abstractmethod 

              
              
                class
              
              
                 Talker(ABC): 
  @abstractmethod 
  
              
              
                def
              
              
                 talk(self): 
  
              
              
                pass
              
            

結(jié)果:

              ##抽象基類不能被實例化
              
>>> Talker() Traceback (most recent call last): File " " , line 1, in TypeError: Can ' t instantiate abstract class Talker with abstract methods talk
              
                ##沒有重寫方法的時候,繼承抽象基類的類 本質(zhì)也是抽象類
                
class
Knigget(Talker): pass ##由于沒有重寫方法talk,因此這個類也是抽象的,不能實例化。如果你試圖這樣做,將出現(xiàn)類似于前面的錯誤消息。
              
                ###繼承后重寫了方法就沒什么問題
                
class
Knigget(Talker): def talk(self): print ( " Ni! " )

##output:
>>> k = Knigget()
>>> isinstance(k, Talker)
True 1
>>> k.talk()
Ni!

?

6.混入模式:多繼承應(yīng)用實例(Mixin 模式)
首先,Mixin模式在python應(yīng)用中十分常見,包括openstack、django等,有大量的Mixin模式應(yīng)用。想要進(jìn)階,就需要理解為什么大部分框架都會用這種模式。
詳細(xì)的谷歌大神關(guān)于動態(tài)語言的設(shè)計模式可以看: http://norvig.com/design-patterns/ppframe.htm?或者《松本行弘的程序世界》里有介紹ruby的混入模式和python一樣。
?
從某種程度上來說,繼承強(qiáng)調(diào) I am,Mixin 強(qiáng)調(diào) I can。
?
以下來自: https://www.liaoxuefeng.com/wiki/897692888725344/923030524000032

在設(shè)計類的繼承關(guān)系時,通常,主線都是單一繼承下來的,例如, Ostrich 繼承自 Bird 。但是,如果需要“混入”額外的功能,通過多重繼承就可以實現(xiàn),比如,讓 Ostrich 除了繼承自 Bird 外,再同時繼承 Runnable 。這種設(shè)計通常稱之為Mixin。

為了更好地看出繼承關(guān)系,我們把 Runnable Flyable 改為 RunnableMixin FlyableMixin 。類似的,你還可以定義出肉食動物 CarnivorousMixin 和植食動物 HerbivoresMixin ,讓某個動物同時擁有好幾個Mixin:

          
            
              
                class 
                
                  Dog
                  
                    (Mammal, RunnableMixin, CarnivorousMixin):
    
                    
                      pass 
                    
                  
                
              
            
          
        

Mixin的目的就是給一個類增加多個功能,這樣,在設(shè)計類的時候,我們優(yōu)先考慮通過多重繼承來組合多個Mixin的功能,而不是設(shè)計多層次的復(fù)雜的繼承關(guān)系。

Python自帶的很多庫也使用了Mixin。舉個例子,Python自帶了 TCPServer UDPServer 這兩類網(wǎng)絡(luò)服務(wù),而要同時服務(wù)多個用戶就必須使用多進(jìn)程或多線程模型,這兩種模型由 ForkingMixin ThreadingMixin 提供。通過組合,我們就可以創(chuàng)造出合適的服務(wù)來。

比如,編寫一個多進(jìn)程模式的TCP服務(wù),定義如下:

          
            
              
                class 
                
                  MyTCPServer
                  
                    (TCPServer, ForkingMixin):
    
                    
                      pass 
                    
                  
                
              
            
          
        

編寫一個多線程模式的UDP服務(wù),定義如下:

          
            
              
                class 
                
                  MyUDPServer
                  
                    (UDPServer, ThreadingMixin):
    
                    
                      pass 
                    
                  
                
              
            
          
        

如果你打算搞一個更先進(jìn)的協(xié)程模型,可以編寫一個 CoroutineMixin

          
            
              
                class 
                
                  MyTCPServer
                  
                    (TCPServer, CoroutineMixin):
    
                    
                      pass 
                    
                  
                
              
            
          
        

這樣一來,我們不需要復(fù)雜而龐大的繼承鏈,只要選擇組合不同的類的功能,就可以快速構(gòu)造出所需的子類。

?


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 亚洲欧洲日本在线 | 艹逼免费视频 | 国产成人综合网在线观看 | 国产福利在线观看永久免费 | 狠狠色狠狠色综合久久第一次 | 亚洲美女精品 | 香蕉香蕉国产片一级一级毛片 | 波多野吉衣一区二区 | 刮伦人妇A片1级 | 老头巨大校花体内驰骋小说文 | 在线成人免费 | 精品综合在线 | 99热久久这里只有精品2010 | 欧美日韩在线第一页 | 日操| 成人午夜精品 | 成人国产在线观看 | 天天看天天爽天天摸天天添 | 天天色天天色 | 成人 日韩 在线 | 欧美精品日韩一区二区三区 | 日本一区中文字幕 | 日韩欧美精品一区 | 日韩欧美一区二区三区免费观看 | 精品欧美一区二区在线看片 | 亚洲一二三区精品 | 92午夜剧场| 成人免费大片a毛片 | 久久久久久中文字幕 | 国产亚洲情侣一区二区无 | 九九热在线观看 | 色在线免费 | 日韩一区二区三区视频 | 日韩精品一区二区三区免费观看 | 国产精品免费久久久免费 | 97精品国产高清在线看入口 | 二区三区四区 | 香蕉久久久久久狠狠色 | 成人区视频爽爽爽爽爽 | 亚洲欧美视频一区二区 | 欧美精品一二三 |