2011-08-12 72 views
29

我想覆蓋我的Python類的__getattribute____setattr__方法。我的用例是通常的用例:我有一些我想處理的特殊名稱,並且我需要其他任何默認行爲。對於__getattribute__,似乎我可以簡單地通過提高AttributeError來請求默認行爲。但是,如何在__setattr__中實現相同?這裏是一個簡單的例子,實現一個具有不可變字段「A」,「B」和「C」的類。如何正確地覆蓋Python中新樣式類的__setattr__和__getattribute__?

class ABCImmutable(SomeSuperclass): 
    def __getattribute__(self, name): 
     if name in ("A", "B", "C"): 
      return "Immutable value of %s" % name 
     else: 
      # This should trigger the default behavior for any other 
      # attribute name. 
      raise AttributeError() 

    def __setattr__(self, name, value): 
     if name in ("A", "B", "C"): 
      raise AttributeError("%s is an immutable attribute.") 
     else: 
      # How do I request the default behavior? 
      ??? 

什麼代替了問號?對於舊式課程,答案顯然是self.__dict__[name] = value,但是文檔表明這對於新式課程來說是錯誤的。

+0

」文檔表明這對於新式班級來說是錯誤的......「並且這並不表示新式班級適合什麼嗎? – Gerrat

+0

爲什麼你不只是實現你的命名字段作爲集合屬性? – katrielalex

+2

不變性僅僅是__setattr__的簡單示例用例。我的實際使用情況有點複雜。我的類繼承了字典,但另外,某些特殊鍵(在運行時確定)可以通過'object.key'而不是'object ['key']'來訪問。我可以使用運行時反射或其他方法將它們添加爲屬性,但使用'__getattr__'和'__setattr__'更容易,性能也不是特別重要。 –

回答

28

這是

super(ABCImmutable, self).__setattr__(name, value) 

在Python 2,或

super().__setattr__(name, value) 
在Python 3

而且

,提高AttributeError你怎麼回落到默認行爲__getattribute__ 。你回退到默認與

return super(ABCImmutable, self).__getattribute__(name) 

Python的2或

return super().__getattribute__(name) 

關於Python 3

提高AttributeError跳過默認處理和去__getattr__,或者只是產生AttributeError在呼叫代碼如果沒有__getattr__

請參閱關於Customizing Attribute Access的文檔。 「

+3

關閉,但你不需要第二個「自我」。你會這樣稱呼它: super(ABCImmutable,self).__ setattr __(name,value) 否則,你會得到「預期的2個參數,但有三個」異常。 – Dave

5

SomeSuperclass.__setattr__(self, name, value)

+0

難道我不需要在某個地方打電話給'super'嗎?至少在一般情況下? –

+0

@Ryan Thompson我很確定你可以使用'super()'來代替'SomeSuperclass',但我試圖追蹤它是否特定於Python 3. –

+0

@Ryan Thompson看看[Python 2的例子對於Raymond Hettinger的「Python's super()被認爲是超級!」 (http://code.activestate.com/recipes/577721-how-to-use-super-effectively-python-27-version/),它看起來像是'super(ABCImmutable,self).__ setattr__ (self,name,value)'在Python 2中。我會用我認爲應該是正確的調用來更新我的答案。 –

相關問題