我有两个共享方法名的父类。我想对它们进行子类化,并将它们的方法以不同的名称重新分配给子类。这变得很复杂,因为这些方法也使用具有共享名称的其他方法。有争议但最小的例子:
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。
我理解这是因为";自我;实际上指向Foo((,因此方法";打印";以及";得到";由于Foo1是MRO中的第一个,因此指向Foo1的方法。
对于我的用例来说,Foo((拥有"是没有意义的;打印";以及";得到";方法,仅";print1";以及";print2";。这让我怀疑我做错了。有没有更好的方法来构建一个正确继承Foo1和Foo2中这些方法的子类?
让类包装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
一个选项是使用composition,其中新的类实例只是原始类的两个实例的包装。您的方法将委托给适当实例的方法。
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
您还可以在类级别而不是实例级别执行组合。只有当Foo1
和Foo2
方法的函数签名与Foo
方法的所需签名兼容时,这才会起作用。
class Foo:
print1 = Foo1.print
print2 = Foo2.print
get1 = Foo1.get
get2 = Foo2.get
在任何一种情况下,都必须定义Foo.__init__
来接受Foo1.__init__
和Foo2.__init__
的任何必要参数,并确保将它们传递给正确的参数。