簡體   English   中英

Python繼承和super()

[英]Python Inheritance and super()

為什么在使用“直接”調用時用super()調用父類不能正常工作?

class A(object):
    def __init__(self, x):
        self.x = x
        print("Inside A __init__. x = %s" % self.x)
class B(object):
    def __init__(self, y):
        self.y = y
        print("Inside B __init__. y = %s" % self.y)
class C(A,B):
    def __init__(self, z):
        super(C, self).__init__(6)
        super(C, self).__init__(5)
        #1.    A.__init__(self,6)
        #2.    B.__init__(self,5)
        self.z = z
        print("Inside C __init__. z = %s" % self.z)
if __name__ == "__main__":
    log = C(2)

使用未注釋的“超級”,我得到的結果是:

Inside A __init__. x = 6
Inside A __init__. x = 5
Inside C __init__. z = 2

因此,永遠不會調用“ B”類初始化的代碼。 但是在使用注釋行“#1”和“#2”之后,代碼將按預期工作:

Inside A __init__. x = 6
Inside B __init__. y = 5
Inside C __init__. z = 2

問題:

  1. 這種奇怪的“ super()”行為的原因是什么?
  2. super()可以在'B'中調用init嗎?
  3. 還有其他方法可以從Parent類調用所有“ init ”嗎?

一個答案,應該被視為super工作方式而非實際編寫代碼的一個示例:

class A(object):
    def __init__(self, x):
        self.x = x
        print("Inside A __init__. x = %s" % self.x)
class B(object):
    def __init__(self, y):
        self.y = y
        print("Inside B __init__. y = %s" % self.y)
class C(A,B):
    def __init__(self, z):
        super(C, self).__init__(6)
        super(A, self).__init__(5)
        self.z = z
        print("Inside C __init__. z = %s" % self.z)
if __name__ == "__main__":
    log = C(2)

每個類都有一個方法解析順序 (MRO),用於查找繼承的函數。 對於C ,該順序為

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

super(foo, bar)type(bar)的MRO中提供對foo之后的下一個類的引用(確實是對它的代理type(bar) super(C, self)提供對A的引用(實際上是代理),因此A.__init__是結果調用。 但是, super(A, self)提供了B的代理,從而導致了對B.__init__的調用。

不過,一般規則是,您實際上並不知道接下來將調用哪種方法,因為您不一定知道self的類型(它可能是具有不同於MRO實例的MRO的后代類的實例。 C )。 為了正確使用super ,您需要確保所有潛在的類都在使用它,以便始終正確分派方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM