2010-06-29 108 views
12

我只花了太長像下面這樣的錯誤:Python:類可以禁止客戶端設置新的屬性嗎?

>>> class Odp(): 
    def __init__(self): 
     self.foo = "bar" 


>>> o = Odp() 
>>> o.raw_foo = 3 # oops - meant o.foo 

我有一個屬性的類。我試圖設置它,並想知道爲什麼它沒有效果。然後,我回到原來的類定義,並看到該屬性被命名爲稍有不同。因此,我創建/設置了一個新的屬性,而不是其中的一個。

首先,這不正是靜態類型語言應該防止的錯誤類型嗎?在這種情況下,動態類型的優點是什麼?

其次,在定義Odp時,有沒有一種方法可以禁止這種情況,從而爲自己省去了麻煩?

+1

可能的重複:http://stackoverflow.com/questions/3079306/how-to-protect-againt-typos-when-setting-value-for-class-members – detly 2010-06-29 03:06:30

回答

16

您可以實現__setattr__方法爲目的 - 這比它常常被誤用爲目的(例如,__slots__自動是「失去」的時候,類繼承自__slots__更強大,而__setattr__生存,除非明確覆蓋)。

def __setattr__(self, name, value): 
    if hasattr(self, name): 
    object.__setattr__(self, name, value) 
    else: 
    raise TypeError('Cannot set name %r on object of type %s' % (
        name, self.__class__.__name__)) 

你必須確保hasattr成功爲你做希望能夠通過在類級別設置的屬性或通過在__init__方法使用object.__setattr__而設置,例如名稱比直接屬性分配。 (要禁止設置屬性而不是其實例您必須使用類似的特殊方法定義自定義元類)。

+0

你爲什麼選擇TypeError?也許是錯誤的,我腦海中有'AttributeError'。 – n611x007 2015-01-21 10:04:22

+2

「不支持XX分配」消息(例如對於項目)使用「TypeError」,更容易混淆措辭「沒有屬性XX」的人使用'AttributeError',所以我猜或者確定(儘管不完美)。 – 2015-01-21 15:01:56

相關問題