日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python super用法

發布時間:2023/12/18 python 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python super用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

?

?

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 = xclass B(A):def __init__(self,x,y):super(B,self,).__init__(x)self.y = ya = 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 objdef __getattr__(self, name):return getattr(self._obj, name)# Delegate attribute assignmentdef __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() hereprint('C.__init__')

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

>>> c = C() Base.__init__ B.__init__ A.__init__ C.__init__ >>>

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

>>> C.__mro__ (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>) >>>

為了實現繼承,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

轉載于:https://www.cnblogs.com/-wenli/p/11343451.html

總結

以上是生活随笔為你收集整理的python super用法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。