2012-09-21 124 views
6

我正在寫一個裝飾器,需要訪問私有變量,並發現這種差異。任何人都可以解釋嗎?Python的「私人」名稱mangling和實例與類的屬性

(Python 2.5的)

命名重整作品如預期的類中定義的屬性:

實例屬性不工作(這是我們應該做的是正確的方法是什麼? )

>>> class Tester(object): 
...  def __init__(self): 
...   self.__foo = "hi" 

>>> t = Tester() 
>>> t._Tester__foo 
AttributeError: 'Tester' object has no attribute '_Tester__foo' 

PS 「班級屬性」是否適合這些?他們不是靜態的,但如果你把其中的一個列表,或其他一些可變類型,它是共享的...

更新

事實上,第二個例子中正常工作了。這是一個硬件問題(重新啓動)。

+2

類屬性是正確的詞。他們*總是*共享。可變性不重要。除非詢問你是否可以改變給定的對象,否則它幾乎從不重要。 – delnan

+0

我可以提出這個問題嗎?還是有人看到保持它的價值?我無法重現我的原始問題。它似乎按預期工作。 – Rafe

+1

寧願留下它,因爲@MartijnPieters在很多Python測試中一直在測試這個問題。 – jsbueno

回答

9

那實際上是不是是正確的。

名稱改變發生在創建階段;任何涉及錯位名稱的函數都會被調整。

我無法重現你的榜樣,至少在Python版本2.4,2.5,2.6,Mac上的3.1和3.2:

>>> class Tester(object): 
...  def __init__(self): 
...   self.__foo = "hi" 
... 
>>> Tester()._Tester__foo 
'hi' 
>>> Tester().__foo 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: 'Tester' object has no attribute '__foo' 

如果拆卸功能字節碼,你可以看到它的名字已經錯位還有:

>>> import dis 
>>> dis.dis(Tester.__init__) 
    3   0 LOAD_CONST    1 ('hi') 
       3 LOAD_FAST    0 (self) 
       6 STORE_ATTR    1 (_Tester__foo) 
       9 LOAD_CONST    0 (None) 
      12 RETURN_VALUE   

我檢查了compiler source所有名是通過壓榨機,即一直保持自2002年以來至少同一個代碼路徑運行。

是的,類屬性和實例屬性是正確的術語。類屬性始終是共享的,但分配給實例的實例上的屬性。突變列表或其他可變對象與屬性分配不同。

+0

也適用於3.2。 – delnan

+0

你說得對。我不知道那裏發生了什麼。我碰巧重啓了我的電腦,所以我只能稱之爲IT問題,「你試過關掉它嗎?」 ;) – Rafe