2017-02-22 29 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來創建一個新的動物,這應該可以。