2013-10-10 91 views
71

我通過讓它調用多個功能,這樣分手了我的類的構造函數:實例屬性屬性名稱之外定義__init__

class Wizard: 
    def __init__(self, argv): 
     self.parse_arguments(argv) 
     self.wave_wand() # declaration omitted 

    def parse_arguments(self, argv): 
     if self.has_correct_argument_count(argv): 
      self.name = argv[0] 
      self.magic_ability = argv[1] 
     else: 
      raise InvalidArgumentsException() # declaration omitted 

# ... irrelevant functions omitted 

雖然我的翻譯順利地執行我的代碼,pylint的有一個投訴:

Instance attribute attribute_name defined outside __init__

粗略的Google搜索目前沒有結果。保持__init__中的所有構造函數邏輯看起來沒有組織,並且關閉Pylint警告也似乎是hack-ish。

什麼是/ Pythonic方式來解決這個問題?

+4

警告只是說它說什麼。如果你在構造函數外初始化實例變量,我認爲它違反了[POLS](http://en.wikipedia.org/wiki/Principle_of_least_astonishment)。嘗試內聯'parse_arguments'或使用'__init__'中函數的返回值初始化變量,我猜,pylint會很開心。 – miku

回答

17

只需從parse_arguments()返回一個元組,然後根據需要解壓到__init__內的屬性。

此外,我會建議您使用例外代替使用exit(1)。你得到回溯,你的代碼是可重用的,等等。

class Wizard: 
    def __init__(self, argv): 
     self.name,self.magic_ability = self.parse_arguments(argv) 

    def parse_arguments(self, argv): 
     assert len(argv) == 2 
     return argv[0],argv[1] 
+0

由於這是一個相對簡單的程序,主代碼將構建一個「嚮導」(主類),我認爲異常是過度的。 –

+1

@StevenLiao這一切都很好,但它的可讀性更強,代碼量更少,併爲將來培養良好的習慣。由你決定。 – roippi

+0

好的,但是如果只想通過在特殊情況下調用parse_arguments來添加這些屬性,該怎麼辦?在這種情況下,將屬性設置爲「無」是更好的解決方案。 – Soldalma

71

這個消息背後的想法是爲了可讀性。我們希望通過閱讀__init__方法來找到實例可能具有的所有屬性。

雖然您可能仍然想將初始化分割爲其他方法。在這種情況下,您可以簡單地在__init__中將屬性分配給None(帶有一些文檔),然後調用子初始化方法。