如何动态调用每个父级的__init__

How to call the __init__ of each parent dynamically

我读过 the most similar question on SO to my question, which was about single-parent inheritance and the only answer that mentioned multi-parent inheritance advised the reader to use the static form of calling that method (SomeSuperClass.someMethod(self, args)), which, as pointed out in the comments 并不总是干净的。

我正在寻求一种方法来调用特定超类 SomeSuperClass 的特定方法 someMethod 动态 ,因此:

class SomeSuperClass():
    def someMethod(self, args):
        print("Hello,", end="")

class Subclass(SomeSuperClass, OtherSuperClass):
    def someMethod(self, args):

        # static calling (I do not want this solution)
        SomeSuperClass.someMethod(self, args)

        # dynamic calling (I want this one)
        (my SomeSuperClass-ness).someMethod(args)

        print("world!")

这是我实际测试过并想要运行的代码:

class Something():
    def __init__(self, a, b) -> None:
        self.sum = a+b


class SomethingElse():
    def __init__(self, c, d) -> None:
        self.product = c * d


class Both(Something, SomethingElse):
    def __init__(self, a, b) -> None:

        # sadly this does not work
        super(Something, self).__init__(a, b)
        super(SomethingElse, self).__init__(a, b)

        # the following works, but is static and does not use super
        # Something.__init__(self, a, b)
        # SomethingElse.__init__(self, a, b)

b = Both(10, 20)

print(b.sum, b.product)

运行 此代码导致以下错误:

TypeError: object.__init__() takes exactly one argument (the instance to initialize)

显然它正在尝试调用 object__init__。在这种情况下,如何正确使用 super 才能真正调用适当的 __init__s?

super() 函数将在您指定的 之后将 委托给父级 - 请参阅 here,具体说明如下:

The object-or-type determines the method resolution order to be searched. The search starts from the class right after the type.

所以要正确使用,应该用super()来指代Something,用super(Something, self)来指代SomethingElse;您可以通过阅读 Both class:

__mro__ 属性 查看顺序
class Something():
    pass

class SomethingElse():
    pass

class Both(Something, SomethingElse):
    pass

print(Both.__mro__)

哪个会告诉你顺序:

(<class '__main__.Both'>, <class '__main__.Something'>, <class '__main__.SomethingElse'>, <class 'object'>)

并解释为什么您在第二次调用 super(...).__init__(...) 时最终调用 object.__init__