Python 多重继承:发生了意想不到的事情。。。?
我正在用python自学oops概念。我意外地在子类C的init方法中键入了B.。_uinit_uu。这是代码Python 多重继承:发生了意想不到的事情。。。?,python,oop,output,multiple-inheritance,Python,Oop,Output,Multiple Inheritance,我正在用python自学oops概念。我意外地在子类C的init方法中键入了B.。_uinit_uu。这是代码 class A: def __init__(self): print('A') class B: def __init__(self): print('B') class C(A,B): def __init__(self): print('C') B().__init__() c1 = C(
class A:
def __init__(self):
print('A')
class B:
def __init__(self):
print('B')
class C(A,B):
def __init__(self):
print('C')
B().__init__()
c1 = C()
这就是输出
C
B
B
为什么要打印两次B?在C的init方法中创建B的实例。然后显式调用B的init方法。您想要:
class C(A,B):
def __init__(self):
print('C')
super().__init__(self)
在C的init方法中创建B的实例,然后显式调用B的init方法。您想要:
class C(A,B):
def __init__(self):
print('C')
super().__init__(self)
根据python文档,它说 _init_u;是一种特殊的Python方法,当内存不足时会自动调用它 分配给一个新对象。 我们还可以显式地调用uuu init_uuu方法,这就是您在上述代码中所做的。 B是构造函数调用,调用了第一个_uinit。 在uuu init uuu被你明确地调用之后。所以两次
电话已经打了 根据python文档,它说 _init_u;是一种特殊的Python方法,当内存不足时会自动调用它 分配给一个新对象。 我们还可以显式地调用uuu init_uuu方法,这就是您在上述代码中所做的。 B是构造函数调用,调用了第一个_uinit。 在uuu init uuu被你明确地调用之后。所以两次
电话已经打了 确保初始化父基类的正确方法如下:您没有指定Python是Python 2还是Python 3,因此我要确保您的类继承自类对象: 您可以执行以下操作:
class A():
def __init__(self):
print('A')
class B():
def __init__(self):
print('B')
class C(A,B):
def __init__(self):
print('C')
A.__init__(self)
B.__init__(self)
c1 = C()
确保初始化父基类的正确方法如下:您没有指定Python是Python 2还是Python 3,因此我要确保您的类继承自class对象: 或者,您可以简单地执行以下操作:
class A():
def __init__(self):
print('A')
class B():
def __init__(self):
print('B')
class C(A,B):
def __init__(self):
print('C')
A.__init__(self)
B.__init__(self)
c1 = C()
你的问题是什么?为什么这个B被打印两次?使用调试器并设置断点;说真的,您创建了一个C实例,这意味着创建了a、B,最后是C,您创建了另一个完全独立的B实例。也就是说,拿着书读一读。特别是,您永远不会声明您期望的内容,因为通过编写B来创建B类的实例会自动执行B的uuu init_uu方法。通过编写B.uuuu init_uuuuu,实际上调用B的uuu init_uuuu两次-一次是在创建实例B时隐式调用,一次是显式调用uuu init_uuu。你的问题是什么?为什么要打印两次?使用调试器并设置断点;说真的,您创建了一个C实例,这意味着创建了a、B,最后是C,您创建了另一个完全独立的B实例。也就是说,拿着书读一读。特别是,您永远不会声明您期望的内容,因为通过编写B来创建B类的实例会自动执行B的uuu init_uu方法。通过编写B.uuu init_uuu,实际上调用了B的uuu init_uuu两次-一次是在创建实例B时隐式调用,一次是显式调用uuu init_uu。这还不完全。A。此外,对于某些场景,实际上需要完全覆盖_uinit _uu,这样,如果开发人员知道他/她在做什么,A和B实现就可以自由地以不同的方式初始化它们的实例。它不会为任何特定的静态基类调用uuu init uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu???当然,它将遵循MRO,并将调用A。在本例中,因为C继承自A和B,而A已定义了。如果A继承自对象以外的其他对象,该怎么办?如果从C的子类的实例调用C.uuu init_uuuuu会怎么样?如果你打算使用super,你需要在整个层次结构中始终如一地使用它。这还不完全。A。此外,对于某些场景,实际上需要完全覆盖_uinit _uu,这样,如果开发人员知道他/她在做什么,A和B实现就可以自由地以不同的方式初始化它们的实例。它不会为任何特定的静态基类调用uuu init uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu???当然,它将遵循MRO,并将调用A。在本例中,因为C继承自A和B,而A已定义了。如果A继承自对象以外的其他对象,该怎么办?如果从C的子类的实例调用C.uuu init_uuuuu会怎么样?如果你打算使用super,你需要在整个层次结构中一致地使用它
假设OP使用的是Python 3;否则,他定义的是老式类,这完全是错误的。@chepner是的,我使用的是python3。我应该在这里使用什么新样式类?新样式/旧样式的区别仅在Python 2中相关。Python3中的所有类都是新样式的类;没有其他选项。@MayankPant如果您使用的是Python3,那么所有类最终都是从object派生的,因此总是“新样式”类;否则,他定义的是老式类,这完全是错误的。@chepner是的,我使用的是python3。我应该在这里使用什么新样式类?新样式/旧样式的区别仅在Python 2中相关。Python3中的所有类都是新样式的类;没有其他选项。@MayankPant如果您使用的是Python3,那么所有类最终都是从object派生的,因此总是“新样式”类。