Python 多重继承:发生了意想不到的事情。。。?

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(

我正在用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()

这就是输出

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派生的,因此总是“新样式”类。