想象一下这样一种情况:大量的动物类无法修改,都来自同一个父类" Animal",并且每个实现一个名为&的方法#34; make_noise"每个签名略有不同,但都具有共享参数卷:
class Cat(Animal)
def make_noise(volume, duration)
-some code here-
class Mouse(Animal)
def make_noise(volume, pitch)
-some different code here-
一个不同的"控制器" class,也无法修改,指示这些动物实例的列表(我已填充的列表)在特定音量(以及适当的持续时间/音高/等)发出声音。但是,我需要在控制器和动物类之间修改" make_noise"在所有动物类中,我可以在发出声音之前减小音量值。
一种选择是做一些事情:
def animal_monkeypatcher(animal_class, volume_reduction_factor):
class QuietAnimal(animal_class)
def make_noise(volume, **kwargs)
volume = volume * volume_reduction_factor
super(QuietAnimal, self).make_noise(volume, **kwargs)
但是,我还需要挑选这些对象,而这并不适用于这种方法。我想到的下一个方法就是一个类似于动物实例的类......
class QuietAnimal():
def __init__(animal_class, init_kwargs):
self.animal = animal_class(**init_kwargs)
def make_noise(volume, **kwargs)
volume = volume * volume_reduction_factor
self.animal.make_noise(volume, **kwargs)
def lots of other functions.....
然而,这也不合适,因为控制器有时需要创建新的动物实例。它通过获取动物的类(即QuietAnimal而不是Mouse)然后使用相同的init_kwargs组来创建它,这与QuietAnimal的签名不匹配,所以我们再次陷入困境。 ..
目前我有一个可怕的黑客攻击,它基本上会根据是否传入了animal_class来分配init,并在某些类变量中记录一些信息。它坦率地说是可怕的,如果我需要创造一种以上的动物(在我的用例中,我不是,但仍然......),这是无用的。它也是垃圾,因为我必须包括所有动物的所有方法。
为了实现上述目的,包装/代理/这些类的适当方法是什么?一些示例代码将不胜感激。我是Python新手。