2012-02-09 28 views
12

雖然編碼一個新的類與Spyder的 IDE,並使用pylint的檢查的最終結果,我遇到了錯誤信息的使用__dict__的(但代碼按預期工作,沒有錯誤)。Python化:在功能自.__ init__類

上下文:在構造函數中,我想創建新成員(相當多)。通常情況下,這些都足以很少,所以我用這個編碼:

class MyClass(): 
    def __init__(self): 
     self.a = ... 
     self.b = ... 

但在許多成員的情況下(比方說10),全部設置爲相同的初始值(假設他們都是字典()) ,我很想這樣做:

class MyClass(): 
    def my_method(self): 
     print self.c 

錯誤

class MyClass(): 
    def __init__(self): 
     _vars = ["a", "b", "c", ...] 
     for _var in _vars: 
      self.__dict__[_var] = dict() 
在類

而且,我是用指的一員pylint的(在Spyder的):

當使用這個文件pylint的,我有一個錯誤信息說:

MyClass.my_method:的 'MyClass的' 實例沒有「c'member 。

但是,代碼運行良好,沒有錯誤,即。我可以毫無問題地訪問成員'c'。

問題:這是一個正確的編碼,或者我應該避免這樣的初始化成員方法?

+2

我不知道你想用'MyClass'到底該怎麼做,但它聽起來像是你可能會投資於一個'collections.defaultdict( )'。請參閱http://docs.python.org/library/collections.html#collections.defaultdict。仍然對其他人不得不說的修改自我.__ dict__感興趣,而不是創建恰好是字典的實例變量。 – Noah 2012-02-09 03:01:50

+0

@Noah謝謝Noah,我不知道defaultdict類。這聽起來很有趣!我現在看到我已經爲我的代碼編寫了幾個「工具」,這些工具很可能是在一些更好的編碼的Python模塊中創建的(例如,我創建了一個簡單的東西,似乎有點像defaultdict,儘管不太複雜)。非常感謝。 – mhavel 2012-02-09 05:35:06

回答

16

是的,這是合理的直接更新實例字典。或者,您可以使用setattr來更新變量。我已經看到在生產代碼中使用這兩種方法。

隨着setattr沒有必要直接觸摸實例字典:

class MyClass(): 
    def __init__(self): 
     for var in 'a', 'b', 'c': 
      setattr(self, var, dict()) 

但如果你直接更新實例字典,有幾個可能的改進考慮。例如,使用vars()代替__dict__有一點更好看。此外,您還可以使用dict.update方法與關鍵字參數:

class MyClass(): 
    def __init__(self): 
     vars(self).update(a=dict(), b=dict(), c=dict()) 
+1

謝謝雷蒙德,你的回答非常明確和有幫助(至少對我而言)。看來我現在已經開始缺少一些Python背景......必須深入研究一本書或者:) – mhavel 2012-02-09 05:38:49

5

這的確是很好,但我把它通常建議,以避免與__dict__直接搞亂。例如,如果你想在後來的道路上爲你的對象的屬性放置一個自定義的setter?

在您的例子情況下,你可以簡單地更換線在你的for循環有以下:

setattr(self, _var, dict()) 
+0

謝謝你。這個功能在這種情況下確實很方便。我會試試看。 – mhavel 2012-02-09 05:39:29