說說Python 2.x中的super關(guān)鍵字

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

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

子類C重寫了父類B中同名方法method,在重寫的實現(xiàn)中通過super實例化的代理對象調(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外接受一個或者或者兩個參數(shù),如同注釋聲明的一樣,接受兩個參數(shù)時返回的是綁定的super實例,省略第二個參數(shù)的時候返回的是未綁定的
super對象。

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

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
<bound method B.test of <__main__.B object at 0x02DA3570>>
>>> super(B, b).klass_meth
<bound method type.klass_meth of <class '__main__.B'>>
>>> super(B, b).static_meth
<function static_meth at 0x02D9CC70>
>>> super(B, B).test
<unbound method B.test>
>>> super(B, B).klass_meth
<bound method type.klass_meth of <class '__main__.B'>>
>>> super(B,B).satic_meth
>>> super(B,B).static_meth
<function static_meth at 0x02D9CC70>

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

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

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

參考資料:

python doc about super

Descriptor HowTo Guide

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評論 19 139
  • 本文翻譯自python descriptor guide 摘要 本文定義了描述符,總結(jié)了其中的協(xié)議,并且介紹如何調(diào)...
    大蟒傳奇閱讀 1,278評論 0 5
  • Python進(jìn)階-繼承中的MRO與super @(Python)[python, python進(jìn)階] [TOC] ...
    理查德成閱讀 1,648評論 2 10
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,835評論 18 399
  • 生活是什么?當(dāng)你決定愿意和他共度一生的時候請你拎清腦子好好想想,你是不是真的能夠承受在她生病住院死去或者難受委屈離...
    一只貔貅閱讀 315評論 0 0

友情鏈接更多精彩內(nèi)容