[英]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
問題:
一個答案,應該被視為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.