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

python super用法

系統 1717 0

?

?

?

super()用法

功能

            super功能:super函數是子類用于調用父類(超類)的一個方法。
          

用法

            
              1
            
            
              .在子類 __init__() 方法中正確的初始化父類
            
            ,保證相同的基類只初始化一次。
            

2 .覆蓋特殊方法。
            
              3
            
            .解決多重繼承中,子類重復調用父類方法的問題。
          

注意

            
              super()繼承只能用于新式類,用于經典類時就會報錯。
新式類:必須有繼承的類,如果無繼承的,則繼承object
經典類:沒有父類,如果此時調用super就會出現錯誤:『super() argument 
            
            
              1
            
             must be type, not classobj)
          

?

?

在子類__init__()方法中正確初始化父類,保證相同的基類只初始化一次

            
              #
            
            
               假如說在父類中實現了一個方法,你想在子類中使用父類的這個方法并且做一定擴展但是又不想完全重寫,并且這個場景中的繼承屬于多繼承,那么super()就出場了,可以實現方法的增量修改。
            
            
              
#
            
            
               A(父類)有x屬性,B(子類)想添加y屬性:
            
          
            
              class
            
            
               A(object):
    
            
            
              def
            
            
              __init__
            
            
              (self,x):
        self.x 
            
            =
            
               x


            
            
              class
            
            
               B(A):
    
            
            
              def
            
            
              __init__
            
            
              (self,x,y):
        super(B,self,).
            
            
              __init__
            
            
              (x)
        self.y 
            
            =
            
               y

a  
            
            = A(2
            
              )
b  
            
            = B(2,4
            
              )

            
            
              print
            
            
              (a.x)

            
            
              print
            
            (b.x,b.y)
          

?

?

覆蓋Python特殊方法

            
              class
            
            
               Proxy:
    
            
            
              def
            
            
              __init__
            
            
              (self, obj):
        self._obj 
            
            =
            
               obj

    
            
            
              #
            
            
               Delegate attribute lookup to internal obj
            
            
              def
            
            
              __getattr__
            
            
              (self, name):
        
            
            
              return
            
            
               getattr(self._obj, name)

    
            
            
              #
            
            
               Delegate attribute assignment
            
            
              def
            
            
              __setattr__
            
            
              (self, name, value):
        
            
            
              if
            
             name.startswith(
            
              '
            
            
              _
            
            
              '
            
            
              ):
            super().
            
            
              __setattr__
            
            (name, value) 
            
              #
            
            
               Call original __setattr__
            
            
              else
            
            
              :
            setattr(self._obj, name, value)
            
          
            
              #
            
            
               在上面代碼中,__setattr__() 的實現包含一個名字檢查。 如果某個屬性名以下劃線(_)開頭,就通過 super() 調用原始的 __setattr__() , 否則的話就委派給內部的代理對象 self._obj 去處理。 這看上去有點意思,因為就算沒有顯式的指明某個類的父類, super() 仍然可以有效的工作。
            
          

?

?

解決多重繼承中,子類重復調用父類方法的問題

              
                class
              
              
                 Base:
    
              
              
                def
              
              
                __init__
              
              
                (self):
        
              
              
                print
              
              (
              
                '
              
              
                Base.__init__
              
              
                '
              
              
                )


              
              
                class
              
              
                 A(Base):
    
              
              
                def
              
              
                __init__
              
              
                (self):
        Base.
              
              
                __init__
              
              
                (self)
        
              
              
                print
              
              (
              
                '
              
              
                A.__init__
              
              
                '
              
              )
            

盡管對于大部分代碼而言這么做沒什么問題,但是在更復雜的涉及到多繼承的代碼中就有可能導致很奇怪的問題發生。 比如,考慮如下的情況:

                
                  class
                
                
                   Base:
    
                
                
                  def
                
                
                  __init__
                
                
                  (self):
        
                
                
                  print
                
                (
                
                  '
                
                
                  Base.__init__
                
                
                  '
                
                
                  )


                
                
                  class
                
                
                   A(Base):
    
                
                
                  def
                
                
                  __init__
                
                
                  (self):
        Base.
                
                
                  __init__
                
                
                  (self)
        
                
                
                  print
                
                (
                
                  '
                
                
                  A.__init__
                
                
                  '
                
                
                  )


                
                
                  class
                
                
                   B(Base):
    
                
                
                  def
                
                
                  __init__
                
                
                  (self):
        Base.
                
                
                  __init__
                
                
                  (self)
        
                
                
                  print
                
                (
                
                  '
                
                
                  B.__init__
                
                
                  '
                
                
                  )


                
                
                  class
                
                
                   C(A,B):
    
                
                
                  def
                
                
                  __init__
                
                
                  (self):
        A.
                
                
                  __init__
                
                
                  (self)
        B.
                
                
                  __init__
                
                
                  (self)
        
                
                
                  print
                
                (
                
                  '
                
                
                  C.__init__
                
                
                  '
                
                )
              

如果你運行這段代碼就會發現? Base.__init__() ?被調用兩次,如下所示:

              
                >>> 
                
                  c 
                  
                    = 
                    
                      C
                      
                        ()

                        
                          Base.__init__ 
                          
                            A.__init__ 
                            
                              Base.__init__ 
                              
                                B.__init__ 
                                
                                  C.__init__ 
                                  
                                    >>> 
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            

可能兩次調用? Base.__init__() ?沒什么壞處,但有時候卻不是。 另一方面,假設你在代碼中換成使用? super() ?,結果就很完美了:

                
                  class
                
                
                   Base:
    
                
                
                  def
                
                
                  __init__
                
                
                  (self):
        
                
                
                  print
                
                (
                
                  '
                
                
                  Base.__init__
                
                
                  '
                
                
                  )


                
                
                  class
                
                
                   A(Base):
    
                
                
                  def
                
                
                  __init__
                
                
                  (self):
        super().
                
                
                  __init__
                
                
                  ()
        
                
                
                  print
                
                (
                
                  '
                
                
                  A.__init__
                
                
                  '
                
                
                  )


                
                
                  class
                
                
                   B(Base):
    
                
                
                  def
                
                
                  __init__
                
                
                  (self):
        super().
                
                
                  __init__
                
                
                  ()
        
                
                
                  print
                
                (
                
                  '
                
                
                  B.__init__
                
                
                  '
                
                
                  )


                
                
                  class
                
                
                   C(A,B):
    
                
                
                  def
                
                
                  __init__
                
                
                  (self):
        super().
                
                
                  __init__
                
                ()  
                
                  #
                
                
                   Only one call to super() here
                
                
                  print
                
                (
                
                  '
                
                
                  C.__init__
                
                
                  '
                
                )
              

運行這個新版本后,你會發現每個? __init__() ?方法只會被調用一次了:

              
                >>> 
                
                  c 
                  
                    = 
                    
                      C
                      
                        ()

                        
                          Base.__init__ 
                          
                            B.__init__ 
                            
                              A.__init__ 
                              
                                C.__init__ 
                                
                                  >>>
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            

為了弄清它的原理,我們需要花點時間解釋下Python是如何實現繼承的。 對于你定義的每一個類,Python會計算出一個所謂的方法解析順序(MRO)列表。 這個MRO列表就是一個簡單的所有基類的線性順序表。例如:

              
                >>> 
                
                  C
                  
                    .
                    
                      __mro__

                      
                        (
                        
                          , 
                          
                            , 
                            
                              ,

                              
                                
                                  , 
                                  
                                    ) 
                                    
                                      >>> 
                                    
                                  
                                
                              
                            
                          
                        
                      
                    
                  
                
              
            

為了實現繼承,Python會在MRO列表上從左到右開始查找基類,直到找到第一個匹配這個屬性的類為止。

而這個MRO列表的構造是通過一個C3線性化算法來實現的。 我們不去深究這個算法的數學原理,它實際上就是合并所有父類的MRO列表并遵循如下三條準則:

  • 子類會先于父類被檢查
  • 多個父類會根據它們在列表中的順序被檢查
  • 如果對下一個類存在兩個合法的選擇,選擇第一個父類

老實說,你所要知道的就是MRO列表中的類順序會讓你定義的任意類層級關系變得有意義。

當你使用? super() ?函數時,Python會在MRO列表上繼續搜索下一個類。 只要每個重定義的方法統一使用? super() ?并只調用它一次, 那么控制流最終會遍歷完整個MRO列表,每個方法也只會被調用一次。 這也是為什么在第二個例子中你不會調用兩次? Base.__init__() ?的原因。

?

參考:https://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 色黄视频在线观看 | 黄色小视频在线观看 | 欧美精品国产一区二区三区 | 国产免费一区二区在线看 | 精品国产一区二区三区久久影院 | 日韩欧美在线一区二区三区 | 久久久久久国产精品视频 | 九九国产 | 午夜精品久久久久久久男人的天堂 | 国产97人妻人人做人碰人人爽 | 一级黄毛片 | 美国一级片免费看 | 欧美日色| 干天天| 欧美日批 | 国产苐1页影院草草影院 | 欧美黄色片一级 | 亚洲第一页在线 | 夜夜夜夜爽 | 成人国产网站 | 天天摸天天爽天天澡视频 | 午夜小视频免费观看 | 五月婷婷久久综合 | 亚洲精品国产精品乱码不97 | 天天摸夜夜摸狠狠摸夜夜摸 | 亚洲国产网站 | 天天摸天天爽天天澡视频 | 久草大 | 久久精品天天中文字幕人 | 亚洲精品不卡 | 欧美一区视频在线 | 免费看的久久久久 | 五月丁香综合啪啪成人小说 | 中文字幕久久久 | 色777色 | 日日做日日摸夜夜爽 | 色欲AV蜜臀AV在线观看麻豆 | 国产99视频在线 | 欧美日日日 | 国产情侣啪啪 | 国产中文字幕在线观看 |