国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

深入解析Python編程中super關鍵字的用法

來源:懂視網 責編:小采 時間:2020-11-27 14:29:14
文檔

深入解析Python編程中super關鍵字的用法

深入解析Python編程中super關鍵字的用法:官方文檔中關于super的定義說的不是很多,大致意思是返回一個代理對象讓你能夠調用一些繼承過來的方法,查找的機制遵循mro規則,最常用的情況如下面這個例子所示: class C(B): def method(self, arg): super(C, self).method(arg)
推薦度:
導讀深入解析Python編程中super關鍵字的用法:官方文檔中關于super的定義說的不是很多,大致意思是返回一個代理對象讓你能夠調用一些繼承過來的方法,查找的機制遵循mro規則,最常用的情況如下面這個例子所示: class C(B): def method(self, arg): super(C, self).method(arg)

官方文檔中關于super的定義說的不是很多,大致意思是返回一個代理對象讓你能夠調用一些繼承過來的方法,查找的機制遵循mro規則,最常用的情況如下面這個例子所示:

class C(B):
 def method(self, arg):
 super(C, self).method(arg)

子類C重寫了父類B中同名方法method,在重寫的實現中通過super實例化的代理對象調用父類的同名方法。

super類的初始方法簽名如下:

def __init__(self, type1, type2=None): # known special case of super.__init__
 """
 super(type, obj) -> bound super object; requires isinstance(obj, type)
 super(type) -> unbound super object
 super(type, type2) -> bound super object; requires issubclass(type2, type)
 Typical use to call a cooperative superclass method:

除去self外接受一個或者或者兩個參數,如同注釋聲明的一樣,接受兩個參數時返回的是綁定的super實例,省略第二個參數的時候返回的是未綁定的super對象。

一般情況下當調用繼承的類方法或者靜態方法時,并不需要綁定具體的實例,這個時候使用super(type, type2).some_method就能達到目的,當然super(type, obj)在這種情況下也能夠使用,super對象有自定義實現的getattribute方法也能夠處理。不過,后者一般用來調用實例方法,這樣在查找方法的時候能夠傳入相應的實例,從而得到綁定的實例方法:

class A(object):
 def __init__(self):
 pass

 @classmethod
 def klass_meth(cls):
 pass

 @staticmethod
 def static_meth():
 pass

 def test(self):
 pass

class B(A):
 pass

>>> b = B()
>>> super(B, b).test
>
>>> super(B, b).klass_meth
>
>>> super(B, b).static_meth

>>> super(B, B).test

>>> super(B, B).klass_meth
>
>>> super(B,B).satic_meth
>>> super(B,B).static_meth


初始化super對象的時候,傳遞的第二個參數其實是綁定的對象,第一個參感覺數可以粗暴地理解為標記查找的起點,比如上面例子中的情況:super(B, b).test就會在B.__mro__里面列出的除B本身的類中查找方法test,因為方法都是非數據描述符,在super對象的自定義getattribute里面實際上會轉化成A.__dict['test'].__get__(b, B)。

super在很多地方都會用到,除了讓程序不必hardcode指定類型讓代碼更加動態,還有其他一些具體必用的地方比如元類中使用super查找baseclass里面的new生成自定義的類型模板;在自定義getattribute的時候用來防止無限循環等等。

關于super建議讀者將它與python的描述符一起來理解,因為super就實現了描述符的協議,是一個非數據描述符,能夠幫助大家更好的理解super的使用和工作原理。

同時,有以下4個點值得大家注意:
1、單繼承時super()和__init__()實現的功能是類似的

class Base(object):
 def __init__(self):
 print 'Base create'

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


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

base = Base()

a = childA()
b = childB()

輸出結果:

Base create
creat A Base create
creat B Base create


使用super()繼承時不用顯式引用基類。

2、super()只能用于新式類中

把基類改為舊式類,即不繼承任何基類

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

執行時,在初始化b時就會報錯:

 super(childB, self).__init__()
TypeError: must be type, not classobj

3、super不是父類,而是繼承順序的下一個類

在多重繼承時會涉及繼承順序,super()相當于返回繼承順序的下一個類,而不是父類,類似于這樣的功能:

def super(class_name, self):
 mro = self.__class__.mro()
 return mro[mro.index(class_name) + 1]

mro()用來獲得類的繼承順序。

例如:

class Base(object):
 def __init__(self):
 print 'Base create'

class childA(Base):
 def __init__(self):
 print 'enter A '
 # Base.__init__(self)
 super(childA, self).__init__()
 print 'leave A'


class childB(Base):
 def __init__(self):
 print 'enter B '
 # Base.__init__(self)
 super(childB, self).__init__()
 print 'leave B'

class childC(childA, childB):
 pass

c = childC()
print c.__class__.__mro__

輸入結果如下:

enter A 
enter B 
Base create
leave B
leave A
(, , , , )

supder和父類沒有關聯,因此執行順序是A —> B—>—>Base

執行過程相當于:初始化childC()時,先會去調用childA的構造方法中的 super(childA, self).__init__(), super(childA, self)返回當前類的繼承順序中childA后的一個類childB;然后再執行childB().__init()__,這樣順序執行下去。

在多重繼承里,如果把childA()中的 super(childA, self).__init__() 換成Base.__init__(self),在執行時,繼承childA后就會直接跳到Base類里,而略過了childB:

enter A 
Base create
leave A
(, , , , )

從super()方法可以看出,super()的第一個參數可以是繼承鏈中任意一個類的名字,

如果是本身就會依次繼承下一個類;

如果是繼承鏈里之前的類便會無限遞歸下去;

如果是繼承鏈里之后的類便會忽略繼承鏈匯總本身和傳入類之間的類;

比如將childA()中的super改為:super(childC, self).__init__(),程序就會無限遞歸下去。

如:

 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
 File "C:/Users/Administrator/Desktop/crawler/learn.py", line 10, in __init__
 super(childC, self).__init__()
RuntimeError: maximum recursion depth exceeded while calling a Python object

4、super()可以避免重復調用

如果childA基礎Base, childB繼承childA和Base,如果childB需要調用Base的__init__()方法時,就會導致__init__()被執行兩次:

class Base(object):
 def __init__(self):
 print 'Base create'

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


class childB(childA, Base):
 def __init__(self):
 childA.__init__(self)
 Base.__init__(self)

b = childB()
 Base的__init__()方法被執行了兩次

enter A 
Base create
leave A
Base create
使用super()是可避免重復調用

class Base(object):
 def __init__(self):
 print 'Base create'

class childA(Base):
 def __init__(self):
 print 'enter A '
 super(childA, self).__init__()
 print 'leave A'


class childB(childA, Base):
 def __init__(self):
 super(childB, self).__init__()

b = childB()
print b.__class__.mro()

enter A 
Base create
leave A
[, , , ]

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

文檔

深入解析Python編程中super關鍵字的用法

深入解析Python編程中super關鍵字的用法:官方文檔中關于super的定義說的不是很多,大致意思是返回一個代理對象讓你能夠調用一些繼承過來的方法,查找的機制遵循mro規則,最常用的情況如下面這個例子所示: class C(B): def method(self, arg): super(C, self).method(arg)
推薦度:
標簽: 使用 詳解 解析
  • 熱門焦點

最新推薦

猜你喜歡

熱門推薦

專題
Top
主站蜘蛛池模板: 91精品一区二区三区在线观看 | 欧美精品第1页在线播放 | 中文字幕在线不卡 | 亚洲第一页中文字幕 | 99久久99这里只有免费的精品 | 国产成人无精品久久久久国语 | 国产一区二区三区夜色 | 国产在线中文字幕 | 成人国产在线看不卡 | 最新国产在线播放 | 国产成人精品久久一区二区三区 | 国产精品ⅴ视频免费观看 | 国产成人精品一区二区不卡 | 香蕉久久精品 | 国产传媒一区二区三区四区五区 | 国产热久久精 | 国产一区系列在线观看 | 欧美日韩国产色 | 国产午夜视频 | 日本欧美另类 | 欧美在线视频网 | 日韩成人在线电影 | 国产成人一区二区三区 | 日本一区二区三区高清在线观看 | 国产中文久久精品 | 国产91久久久久久久免费 | 国产一级视频在线观看 | 欧美日韩国产在线 | 天天爽夜夜爽一区二区三区 | 国产精品va在线观看无 | 久久精品国产免费一区 | 欧美性xxxx极品高清 | 亚洲日韩精品欧美一区二区 | 国产日产精品_国产精品毛片 | 日本伊人网 | 国产一级特黄高清免费下载 | 在线欧美a | 久久永久免费视频 | 最新国产精品视频 | 2020年国产高中毛片在线视频 | 伊人久久精品一区二区三区 |