【发布时间】:2015-11-16 13:44:58
【问题描述】:
让Instrument 是一个具有三个函数piano(self)、guitar(self) 和trumpet(self) 的类。该类还有一个play(self) 函数,它将根据类中表示的工具调用正确的方法。
有没有一种方法,只有一个类Instrument(即没有其他抽象类)来定义调用play方法时应该调用的方法?
换句话说,有没有办法做到以下几点:
my_piano = Instrument(piano)
my_piano.play() # calls piano(self) method
my_guitar = Instrument(guitar)
my_guitar.play() # calls guitar(self) method
my_trumpet = Instrument(trumpet)
my_trumpet.play() # calls trumpet(self) method
一个比较简单但代码不太干净的方法是在构造函数中放一个变量,然后在play方法中放很多条件,像这样:
def Instrument(object):
def __init__(self, instrument_type):
self.instrument_type = instrument_type
def play(self):
if instrument_type == 0:
self.piano()
elif instrument_type == 1:
self.guitar()
elif instrument_type == 2:
self.trumpet()
这样做的正确方法是拥有一个Instrumentclass,然后是三个Piano、Guitar 和Trumpet 继承自Instrument 的类。但是对于我的需要,这不会太复杂。
编辑
根据要求,我解释了我的实际问题,这几乎是相同的。
我有一个类ComputeSth,它可以使用五种不同的方法来计算它。它可以以a(self)、b(self)、...、f(self) 的方式计算它。
例如,有时我想根据a 计算,有时我想根据c 计算。如果我这样做很容易:
my_computer = ComputeSth()
my_computer.a()
my_computer.c()
但后来我注意到,为了在我的代码的其他部分轻松使用这个类,我更愿意使用my_computer.compute()。因此,我认为在调用compute(self) 时使用实际计算方法构造实例会很方便。我不想写其他五个类,因为它们实际上不会代表五个不同的对象,而是五种做同样事情的方式。我无法将函数 a,...,f 作为构造函数的输入传递,因为它需要 self。
换句话说,与Instrument 的示例相同,但“现实世界继承”较少。
【问题讨论】:
-
这就是任何面向对象语言中的多态性。您应该为从基类 Instrument 继承的 Piano/Guitar 创建单独的类
-
您可以查看single dispatch,但我不能 100% 确定它适用于方法,我相信这比仅仅玩继承更麻烦。
-
@lejlot 是的,我知道我可以按照您在回答中提出的建议(请参阅我的最后一段)。购买 我想也许可以有一种更简单的方法,就像我提出的那种丑陋但简单且有效的方法。在仪器示例中,通过继承实现了更多逻辑,但在我的实际问题中,它看起来很重,也更复杂。
-
那么你应该描述你的实际问题,否则我们无法给你任何合理的答案。
-
这实际上仍然是继承的“路要走”,因为它们是不同类型的计算。在 python 中,具有多重继承和“mixins”,只有一个方法的子类是可以的