用多重继承调用父类__init__,正确的方法是什么?

假设我有多个继承方案:


class A(object):

    # code for A here


class B(object):

    # code for B here


class C(A, B):

    def __init__(self):

        # What's the right code to write here to ensure 

        # A.__init__ and B.__init__ get called?

有写作两种典型的方法C的__init__:


(老式) ParentClass.__init__(self)

(较新的样式) super(DerivedClass, self).__init__()

但是,在任何一种情况下,如果父类(A和B)没有遵循相同的约定,则代码将无法正常工作(某些代码可能会丢失或多次调用)。


那么又是什么正确的方法呢?说“保持一致,遵循一个或另一个”很容易,但是如果A或B来自第三方图书馆,那又如何呢?有没有一种方法可以确保所有父类构造函数都被调用(以正确的顺序,并且只能调用一次)?


编辑:看看我的意思,如果我这样做:


class A(object):

    def __init__(self):

        print("Entering A")

        super(A, self).__init__()

        print("Leaving A")


class B(object):

    def __init__(self):

        print("Entering B")

        super(B, self).__init__()

        print("Leaving B")


class C(A, B):

    def __init__(self):

        print("Entering C")

        A.__init__(self)

        B.__init__(self)

        print("Leaving C")

然后我得到:


Entering C

Entering A

Entering B

Leaving B

Leaving A

Entering B

Leaving B

Leaving C

请注意,B的init被调用了两次。如果我做:


class A(object):

    def __init__(self):

        print("Entering A")

        print("Leaving A")


class B(object):

    def __init__(self):

        print("Entering B")

        super(B, self).__init__()

        print("Leaving B")


class C(A, B):

    def __init__(self):

        print("Entering C")

        super(C, self).__init__()

        print("Leaving C")

然后我得到:


Entering C

Entering A

Leaving A

Leaving C

请注意,Binit永远不会被调用。因此,似乎除非我知道/控制我从(A和B)继承的类的初始化,否则我无法对我正在编写的类(C)做出安全的选择。


守着星空守着你
浏览 750回答 3
3回答

尚方宝剑之说

如果要从第三方库中繁衍子类类,则不会,没有盲目的方法来调用__init__实际上起作用的基类方法(或任何其他方法),而不管基类的编程方式如何。super使编写旨在协作实现方法的类成为复杂的多重继承树的一部分成为可能,而类继承者不必知道。但是没有办法使用它来正确地继承可能使用或可能不使用的任意类super。本质上,一个类是设计为使用super基类还是直接调用基类进行子类化,是属于该类“公共接口”一部分的属性,因此应进行记录。如果您以库作者所期望的方式使用第三方库,并且库具有合理的文档,则通常会告诉您对特定事物进行子类化需要执行的操作。如果不是,则必须查看要子类化的类的源代码,并查看其基类调用约定是什么。如果你是从一个或多个第三方库的方式,该库作者结合多个类没想到,那么它可能无法始终如一地调用超类的方法在所有; 如果类A是使用的层次结构的一部分,super而类B是不使用super的层次结构的一部分,则不能保证这两种选择都不会起作用。您将必须找出适合每种情况的策略。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python