python class 多重继承中的方法覆盖
Method overriding in python class multiple inheritance
我有一个 Base
class 由两个 classes Adder
和 subtractor
继承,其中我重写了名为 test_func()
以适应各自的 class 属性。
class Base():
def __init__(self, K):
self.K = K
def test_func(self):
'Must be overridden since used by another_func()'
return self.K
def another_func(self):
return self.K * self.test_func()
class Adder(Base):
def __init__(self, K, M):
Base.__init__(self, K)
self.M = M
def test_func(self):
return self.M + self.K
class Subtractor(Base):
def __init__(self, K, N):
Base.__init__(self, K)
self.N = N
def test_func(self):
return self.N - self.K
我正在编写一个名为 Algebra
的超级class,它继承了 Adder
和 Subtractor
。
class Algebra(Adder, Subtractor):
def __init__(self, K, M, N):
Adder.__init__(self, K, M)
Subtractor.__init__(self, K, N)
现在我想在 superclass Algebra
中选择性地使用 Adder
或 Subtractor
中的 test_func()
方法。有什么办法可以做到这一点?我试过了
G = Algebra(K=2, M=5, N=7)
G.test_func()
>> 7
但它只采用 Adder
class 的方法。有没有一种方法可以告诉 superclass 从哪个 class 评估方法?例如,
G.test_func('Adder')
继承的工作方式是
- 大多数时候你会参考 parent class
- 实例化 child class
在你的情况下,而不是
G = Algebra(K=2, M=5, N=7)
你应该说
G = Adder(K=2, M=5, N=7)
然后通过G.test_func()
调用相应的函数
在您的示例中,运行时永远不会知道如何调用 child 方法,因为您已经实例化了 parent object。
获得此结果的唯一方法是重新定义 Algebra.test_func()
以使其明确地以这种方式工作,即:
class Algebra(Adder, Subtractor):
def __init__(self, K, M, N):
Adder.__init__(self, K, M)
Subtractor.__init__(self, K, N)
def test_func(self, which):
if which == "Adder"):
return Adder.test_func(self)
elif which == "Subtractor":
return Subtractor.test_func(self)
else:
raise ValueError("don't know %s" % which)
但这完全是一团糟,是滥用继承的完美例子。继承意味着 "is a" 关系,这意味着 Base
的任何子类都应保持兼容的接口(相同的客户端代码必须能够与任何 Base
子类的实例一起工作) - 以上没有。
现在问问自己:Algebra
是 Adder
还是 Subtractor
?如果是,那么您的设计问题出在 test_func()
本身。否则(Algebra
有一个 Adder
和一个 Subtractor
),不要从 Adder
和 Subtractor
继承,而是使用 composition/delegation。
不要覆盖test_func
;提供两个方法,每个方法调用所需父class的test_func
。
class Algebra(Adder, Subtractor):
def __init__(self, K, M, N):
Adder.__init__(self, K, M)
Subtractor.__init__(self, K, N)
def test_adder_func(self):
return Adder.test_func(self)
def test_subtractor_func(self):
return Subtractor.test_func(self)
我忽略了任何更深层次的问题,比如你为什么在这里选择多重继承。
我有一个 Base
class 由两个 classes Adder
和 subtractor
继承,其中我重写了名为 test_func()
以适应各自的 class 属性。
class Base():
def __init__(self, K):
self.K = K
def test_func(self):
'Must be overridden since used by another_func()'
return self.K
def another_func(self):
return self.K * self.test_func()
class Adder(Base):
def __init__(self, K, M):
Base.__init__(self, K)
self.M = M
def test_func(self):
return self.M + self.K
class Subtractor(Base):
def __init__(self, K, N):
Base.__init__(self, K)
self.N = N
def test_func(self):
return self.N - self.K
我正在编写一个名为 Algebra
的超级class,它继承了 Adder
和 Subtractor
。
class Algebra(Adder, Subtractor):
def __init__(self, K, M, N):
Adder.__init__(self, K, M)
Subtractor.__init__(self, K, N)
现在我想在 superclass Algebra
中选择性地使用 Adder
或 Subtractor
中的 test_func()
方法。有什么办法可以做到这一点?我试过了
G = Algebra(K=2, M=5, N=7)
G.test_func()
>> 7
但它只采用 Adder
class 的方法。有没有一种方法可以告诉 superclass 从哪个 class 评估方法?例如,
G.test_func('Adder')
继承的工作方式是
- 大多数时候你会参考 parent class
- 实例化 child class
在你的情况下,而不是
G = Algebra(K=2, M=5, N=7)
你应该说
G = Adder(K=2, M=5, N=7)
然后通过G.test_func()
在您的示例中,运行时永远不会知道如何调用 child 方法,因为您已经实例化了 parent object。
获得此结果的唯一方法是重新定义 Algebra.test_func()
以使其明确地以这种方式工作,即:
class Algebra(Adder, Subtractor):
def __init__(self, K, M, N):
Adder.__init__(self, K, M)
Subtractor.__init__(self, K, N)
def test_func(self, which):
if which == "Adder"):
return Adder.test_func(self)
elif which == "Subtractor":
return Subtractor.test_func(self)
else:
raise ValueError("don't know %s" % which)
但这完全是一团糟,是滥用继承的完美例子。继承意味着 "is a" 关系,这意味着 Base
的任何子类都应保持兼容的接口(相同的客户端代码必须能够与任何 Base
子类的实例一起工作) - 以上没有。
现在问问自己:Algebra
是 Adder
还是 Subtractor
?如果是,那么您的设计问题出在 test_func()
本身。否则(Algebra
有一个 Adder
和一个 Subtractor
),不要从 Adder
和 Subtractor
继承,而是使用 composition/delegation。
不要覆盖test_func
;提供两个方法,每个方法调用所需父class的test_func
。
class Algebra(Adder, Subtractor):
def __init__(self, K, M, N):
Adder.__init__(self, K, M)
Subtractor.__init__(self, K, N)
def test_adder_func(self):
return Adder.test_func(self)
def test_subtractor_func(self):
return Subtractor.test_func(self)
我忽略了任何更深层次的问题,比如你为什么在这里选择多重继承。