从多个 类 中继承多个具有相同名称的方法
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 包装 Foo1
和 Foo2
实例,而不是使用多重继承。
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 级别而不是实例级别执行合成。这仅在 Foo1
和 Foo2
方法的函数签名与 Foo
方法的所需签名兼容时才有效。
class Foo:
print1 = Foo1.print
print2 = Foo2.print
get1 = Foo1.get
get2 = Foo2.get
无论哪种情况,您都必须定义 Foo.__init__
以接受 Foo1.__init__
和 Foo2.__init__
的任何必要参数,并确保将它们传递给正确的参数。
我有两个共享方法名称的父 类。我想对它们进行子类化,并以不同的名称将它们的方法重新分配给子类。这变得很复杂,因为这些方法也使用具有共享名称的其他方法。做作但最小的例子:
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 包装 Foo1
和 Foo2
实例,而不是使用多重继承。
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 级别而不是实例级别执行合成。这仅在 Foo1
和 Foo2
方法的函数签名与 Foo
方法的所需签名兼容时才有效。
class Foo:
print1 = Foo1.print
print2 = Foo2.print
get1 = Foo1.get
get2 = Foo2.get
无论哪种情况,您都必须定义 Foo.__init__
以接受 Foo1.__init__
和 Foo2.__init__
的任何必要参数,并确保将它们传递给正确的参数。