给出以下3个课程,
class A(object):
def __init__(self):
print('A')
def test(self):
print('1')
class B(A):
def __init__(self):
super(B,self) ## if .__init__() is not given here
print('B')
class C(B, A):
def __init__(self):
super(C, self).__init__()
print('C')
如果我运行D = C()
,它将返回
B
C
如果我运行print(C.__mro__)
,
它将得到(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
。
我认为这意味着将在mro
列表中执行类A。但是,事实并非如此。
我想问为什么.__init__()
对于发生A.__init__()
是必要的。
答案 0 :(得分:7)
那不是不是是什么意思!
我认为您实际上对两件事感到困惑:mro
是什么,以及Python中子类构造函数的性质。让我们先来看mro
。
mro
的意思是“方法解析顺序”,并指定Python解释器查找适当命名的方法的顺序。
因此,假设您具有以下类层次结构:
class A:
def deepest(self):
print('I wonder where this is coming from...')
def deeer(self):
print('deeper from A')
def deep(self):
print('deep from A')
class B(A):
def deeper(self):
print('deeper from B')
def deep(self):
print('deep from B')
class C(B):
def deep(self):
print('deep from C')
c = C()
c.deep()
c.deeper()
c.deepest()
print(c.__mro__)
输出:
deep from C
deeper from B
I wonder where this is coming from...
(<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>)
当我们调用deep
时,Python在C
中查找它,因为C
在mro
中是第一个。它找到了,不再走了。
另一方面,对于deeper
,Python无法在C
中找到它,因此转到层次结构中的下一个B
并找到它。
与deepest
相同,只能在A
中找到。
现在,我们将其连接到__init__
。
在这种情况下,当您从__init__
调用super
时,Python将在层次结构中查找第一个超类B
,并调用其__init__
方法。
但是,如果__init__
的{{1}}方法没有调用B
,则然后链就在那里停了!
与其他语言不同,子类不会自动调用其超类的A.__init__
方法,除非它们当然没有定义自己的__init__
方法,否则就属于__init__
,如上所述。
这符合Python的“我们都同意成年人在这里”的哲学-如果您不想调用超类的c.deeper()
,那么可以这样做,但是后果自负。 / p>
答案 1 :(得分:1)
class A:
def __init__(self):
print('A.__init__()')
class B(A):
def __init__(self):
print('B.__init__()')
super().__init__() # this will call A.__init__()
b = B()
因为这是python行为。如果您拥有A
和B
类,并且A
是B
的父级,并且B
也具有__init__
方法,则应调用{{1 }}。否则,python将覆盖它。您需要显式呼叫!
我们在python中有A.__init__
(类似构造函数)。在某些情况下,您应该手动调用它。它不会像其他语言那样被自动调用。