6

プライベート変数にアクセスする必要があるデコレータを作成しましたが、この不一致が見つかりました。誰もこれを説明できますか?Pythonの "private"名前のマングリングとインスタンスのvsクラスの属性

(パイソン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番目の例では、あまりにも、正常に動作し、実際に

更新彼らは静的ではありませんが、あなたはそれが共有されているものをリスト、またはいくつかの他の可変タイプ、のいずれかを作れば...

。ハードウェアの問題でした(再起動に役立ちました)。

+2

クラス属性は正しい単語です。そして、彼らは常に*共有されています。変異は問題ではありません。あなたが与えられたオブジェクトを突然変異させることができるかどうかを尋ねる時を除いて、それはかなり重要ではありません。 – delnan

+0

この質問をすることはできますか?それとも誰もそれを保つ価値を見ているのですか?元の問題は再現できません。期待どおりに動作するようです。 – Rafe

+1

@MartijnPietersは多くのPythonのテストで問題をテストしてきたので、あちこちに残しておいてください。 – jsbueno

答えて

9

実際にはではなく、となります。

名前のマングリングは、クラス作成時に行われます。変更された名前を参照する関数も同様に調整されます。

私は、少なくともMac上のPythonのバージョン2.4、2.5、2.6、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' 

あなたが名前を台無しにされています見ることができます同様に:私はcompiler sourceすべての名前をチェックしました

>>> 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   

マングラー、少なくとも2002年以来同じままでいるコードパスを介して実行されています。

はい、クラス属性とインスタンス属性が正しい用語です。クラス属性は常に共有されますが、インスタンスの属性はインスタンスに割り当てられます。リストやその他の変更可能なオブジェクトを変更することは、属性の割り当てと同じではありません。

+0

また3.2で動作します。 – delnan

+0

あなたは正しいです。私はそこで何が起こったのか分かりません。私は自分のコンピュータを再起動することになるので、ITの問題と呼ぶだけでいいです。 "もう一度やり直してみましたか?" ;) – Rafe

関連する問題