从多个 类 中继承多个具有相同名称的方法

Inherit multiple methods with same name from multiple classes

我有两个共享方法名称的父 类。我想对它们进行子类化,并以不同的名称将它们的方法重新分配给子类。这变得很复杂,因为这些方法也使用具有共享名称的其他方法。做作但最小的例子:

class Foo1():
    def __init__(self):
        super().__init__()

    def print(self):
        print(self.get())

    def get(self):
        return 1


class Foo2():
    def __init__(self):
        super().__init__()

    def print(self):
        print(self.get())

    def get(self):
        return 2


class Foo(Foo1, Foo2):
    def __init__(self):
        super().__init__()

        self.print1 = super().print
        self.print2 = super(Foo1, self).print


foo = Foo()
foo.print1()
>>> 1
foo.print2()
>>> 1

在上面的示例中,foo.print1() 按预期打印 1,但 foo.print2() 打印 1 而不是 2。我想构建 Foo,使其调用 Foo2 的 print 和 get 方法,从而打印2.

我理解这是因为名称“self”实际上指向 Foo(),因此方法“print”和“get”指向 Foo1 的方法,因为 Foo1 在 MRO 中是第一个。

对于我的用例,Foo() 具有“print”和“get”方法甚至没有意义,只有“print1”和“print2”。这让我怀疑我做错了。有没有更好的方法来构造子类,正确地从 Foo1 和 Foo2 继承这些方法?

让您的 class 包装 Foo1Foo2 实例,而不是使用多重继承。

class Foo:
    def __init__(self):
        foo1 = Foo1()
        foo2 = Foo2()

        self.print1 = foo1.print
        self.print2 = foo2.print

        self.get1 = foo1.get
        self.get2 = foo2.get

一种选择是使用组合,其中新的 class 实例只是原始 classes 的两个实例的包装器。您的方法将委托给适当实例的方法。

class Foo:
    def __init__(self):
        self.foo1 = Foo1()
        self.foo2 = Foo2()

    def print1(self):
        return self.foo1.print()

    def print2(self):
        return self.foo2.print()

    # etc

您也许还可以在 class 级别而不是实例级别执行合成。这仅在 Foo1Foo2 方法的函数签名与 Foo 方法的所需签名兼容时才有效。

class Foo:
    print1 = Foo1.print
    print2 = Foo2.print
    get1 = Foo1.get
    get2 = Foo2.get

无论哪种情况,您都必须定义 Foo.__init__ 以接受 Foo1.__init__Foo2.__init__ 的任何必要参数,并确保将它们传递给正确的参数。