2017-02-22 25 views
0

Q.我应该如何通过常量将参数传递给Python基类?Python将常量参数传递给基类

使用典型示例,我有类CatDog(均源自Animal)。 调用x.sound应返回相应的单词("meow","woof")。

我的问题是,在类的所有实例进行相同的声音,因此,虽然我可以通过一个soundAnimal

class Animal: 
    def __init__(sound): 
     self.sound = sound 

class Dog: 
    def __init__(): 
     super().__init__("woof") 

这似乎是浪费的,因为我们存储"woof"在每种情况下,我有一百万只狗和十亿只猫。我可以用一个方法,而不是那么:

class Animal: 
    @staticmethod 
    def sound(): 
     raise NotImplementedError("Abstract") 

class Dog: 
    @staticmethod 
    def sound(): 
     return "woof" 

但现在,因为我的动物都非常安静,这是很容易错过别人的时候出现了,没有读我的苦心书面文件写入Bird类,只有发现当方法实际上被调用时,他们在蓝色月亮中忘记了该方法。

理想情况下,我想要类似C++的模板,其中Animal类本身采用参数 - 它不能错过而不会导致即时错误,并且不会每个实例占用更多空间。

template<sound> 
class Animal() 
    . . . 

是否有方法可以完成我在Python中完成的任务?

+0

我认为所有的狗实例应该收到相同的实际字符串对象由于字符串interning。 –

+0

我不是很确定,但是你可能需要'__slots__'这个 – vks

+0

@PaulRooney仍然为每个对象都提供了一个指针。另外,在64位系统上指向interned字符串的指针将为8个字节,比“woof”字符串本身长。 –

回答

0

您可以尝试使用工厂设计模式。是这样的:

class AnimalFactory(object): 
    animals={} 

    @staticmethod 
    def registerAnimal(animalName, animalClass): 
     if not hasattr(animalClass, "sound"): 
      raise Exception("All animals need to make a sound") 
     AnimalFactory.animals[animalName]=animalClass 

    @staticmethod 
    def createNewAnimal(animalName): 
     return AnimalFactory.animals[animalName]() 

class Dog: 
    sound="woof" 

AnimalFactory.registerAnimal("dog", Dog) 

dog1=AnimalFactory.createNewAnimal("dog") 
print dog1.sound 

class Cat: 
    pass 

AnimalFactory.registerAnimal("cat", Cat) 

上面的代码产生以下输出

woof 
Traceback (most recent call last): 
    File "animals.py", line 25, in <module> 
    AnimalFactory.registerAnimal("cat", Cat) 
    File "animals.py", line 7, in registerAnimal 
    raise Exception("All animals need to make a sound") 

当然,用户可能会忘记注册类,但只要其它用户使用AnimalFactory来创建一个新的动物,这应该可以。