如何完全调用每个父项的构造函数一次?

问题描述 投票:3回答:2

假设有一个简单的多重继承设置,有两个基类AB以及一个继承自两者的子类C

class A:
    def __init__(self):
        print("Started A's constructor")
        # -- Not calling: super().__init__() --
        print("Ended A's constructor")

class B:
    def __init__(self):
        print("Started B's constructor")
        super().__init__()
        print("Ended B's constructor")

class C(A, B):
    def __init__(self):
        print("Started C's constructor")
        super().__init__()
        print("Ended C's constructor")

打电话

c = C()

我们得到了输出

Started C's constructor
Started A's constructor
Ended A's constructor
Ended C's constructor

如果我想为每个C对象调用两个基类构造函数,并且无法访问基类来添加super().__init__()调用,那么应该更改或添加到C?有没有办法这样做,如果A确实调用super().__init__()它不会破坏? (编辑:要清楚,将super().__init__()添加到A会调用B的构造函数,因为它是MRO中的下一个;为了使它更清晰:code example

更重要的是,在一般情况下,人们想要调用每个祖先的每个__init__方法一次,并且不确定每个__init__函数是否称为super().__init__(),如何确保每个父类被调用一次且仅一次?

如果这是不可能的,这不会破坏基本的面向对象原则吗?简单地说,在这种情况下,A的实现不应该影响B的行为。

python python-3.x oop multiple-inheritance
2个回答
1
投票

A不使用super,因此它不能用于合作继承。相反,根据APython's super() considered super!定义一个包装器。 (假设你不能简单地修复A。)

class A:
    def __init__(self):
        print("Started A's constructor")
        print("Ended A's constructor")


# AWrapper also needs to override each method defined by A;
# those simply delegate their work to the intenral instance of A
# For example,
#
#  def some_method(self, x, y):
#      return self.a.some_method(x, y)
#
class AWrapper:
    def __init__(self, **kwargs):
        self.a = A()
        super().__init__(**kwargs)


class B:
    ...


class C(AWrapper, B):
    ...

0
投票

您可以遍历类对象的__bases__属性来调用每个父类的__init__方法:

class C(A, B):
    def __init__(self):
        print("Started C's constructor")
        for base in self.__class__.__bases__:
            base.__init__(self)
        print("Ended C's constructor")

所以C()输出:

Started C's constructor
Started A's constructor
Ended A's constructor
Started B's constructor
Ended B's constructor
Ended C's constructor
© www.soinside.com 2019 - 2024. All rights reserved.