在几个兄弟类中重写方法的棘手方法需要

时间:2018-03-23 15:34:35

标签: python inheritance override

想象一下这样一种情况:大量的动物类无法修改,都来自同一个父类" 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新手。

1 个答案:

答案 0 :(得分:0)

原来,我需要的是标准"monkey patching"。也不是一个好主意,但是比动态创建类要干净一些。