<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題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關(guān)鍵字專題關(guān)鍵字專題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
        當(dāng)前位置: 首頁 - 科技 - 知識百科 - 正文

        深入解析Python編程中super關(guān)鍵字的用法

        來源:懂視網(wǎng) 責(zé)編:小采 時(shí)間:2020-11-27 14:29:14
        文檔

        深入解析Python編程中super關(guān)鍵字的用法

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

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

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

        子類C重寫了父類B中同名方法method,在重寫的實(shí)現(xiàn)中通過super實(shí)例化的代理對象調(diào)用父類的同名方法。

        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外接受一個(gè)或者或者兩個(gè)參數(shù),如同注釋聲明的一樣,接受兩個(gè)參數(shù)時(shí)返回的是綁定的super實(shí)例,省略第二個(gè)參數(shù)的時(shí)候返回的是未綁定的super對象。

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

        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對象的時(shí)候,傳遞的第二個(gè)參數(shù)其實(shí)是綁定的對象,第一個(gè)參感覺數(shù)可以粗暴地理解為標(biāo)記查找的起點(diǎn),比如上面例子中的情況:super(B, b).test就會在B.__mro__里面列出的除B本身的類中查找方法test,因?yàn)榉椒ǘ际欠菙?shù)據(jù)描述符,在super對象的自定義getattribute里面實(shí)際上會轉(zhuǎn)化成A.__dict['test'].__get__(b, B)。

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

        關(guān)于super建議讀者將它與python的描述符一起來理解,因?yàn)閟uper就實(shí)現(xiàn)了描述符的協(xié)議,是一個(gè)非數(shù)據(jù)描述符,能夠幫助大家更好的理解super的使用和工作原理。

        同時(shí),有以下4個(gè)點(diǎn)值得大家注意:
        1、單繼承時(shí)super()和__init__()實(shí)現(xiàn)的功能是類似的

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

        輸出結(jié)果:

        Base create
        creat A Base create
        creat B Base create


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

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

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

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

        執(zhí)行時(shí),在初始化b時(shí)就會報(bào)錯(cuò):

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

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

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

        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__
        
        

        輸入結(jié)果如下:

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

        supder和父類沒有關(guān)聯(lián),因此執(zhí)行順序是A —> B—>—>Base

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

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

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

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

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

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

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

        比如將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()可以避免重復(fù)調(diào)用

        如果childA基礎(chǔ)Base, childB繼承childA和Base,如果childB需要調(diào)用Base的__init__()方法時(shí),就會導(dǎo)致__init__()被執(zhí)行兩次:

        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__()方法被執(zhí)行了兩次
        
        enter A 
        Base create
        leave A
        Base create
        使用super()是可避免重復(fù)調(diào)用
        
        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
        [, , , ]
        

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        深入解析Python編程中super關(guān)鍵字的用法

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

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 免费视频精品一区二区| 精品亚洲成在人线AV无码| 九九免费观看全部免费视频| 国产亚洲福利一区二区免费看| 亚洲日本天堂在线| 午夜精品在线免费观看| 黑人粗长大战亚洲女2021国产精品成人免费视频 | 免费黄色毛片视频| 亚洲AV日韩AV一区二区三曲| 国产又大又长又粗又硬的免费视频 | 亚洲国产成人久久一区WWW| 黄色大片免费网站| 亚洲线精品一区二区三区| 久久亚洲熟女cc98cm| 久草免费福利资源站| 亚洲人成免费网站| 免费黄网在线观看| 免费在线观看亚洲| 日韩一卡2卡3卡4卡新区亚洲| a级毛片免费播放| 亚洲成a人片7777| 男女啪啪永久免费观看网站| 美女一级毛片免费观看| 亚洲中文久久精品无码ww16| 国产免费一区二区视频| 亚洲天堂一区二区三区| 全部免费国产潢色一级| a级片免费在线观看| 亚洲a视频在线观看| 亚洲AV无码一区二区三区在线观看| 老司机精品免费视频| 亚洲午夜福利精品久久| 男女作爱在线播放免费网站| 亚洲一区精品视频在线| 亚洲精品成a人在线观看| 无人在线观看免费高清| 欧美激情综合亚洲一二区| 亚洲国产精品国自产拍AV| 成人毛片视频免费网站观看| 亚洲w码欧洲s码免费| 免费a级毛片大学生免费观看|