6

私はプライベート変数にアクセスする必要があるデコレータを書いていましたが、この不一致を見つけました。誰かがこれを説明できますか?

(Python 2.5)

ネーミングマングリングは、クラスで定義された属性に対して期待どおりに機能します。

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

>>> t = Tester()
>>> t._Tester__foo
'hi'

インスタンス属性は機能しません(これは私たちが正しく行うことになっている方法ですか?)

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

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

PS「クラス属性」はこれらの正しい言葉ですか?それらは静的ではありませんが、それらのリストの1つ、または他の可変タイプを作成すると、共有されます...

アップデート

実際、2番目の例も問題なく機能します。これはハードウェアの問題でした(再起動が役立ちました)。

4

1 に答える 1

10

それは実際には正しくありません。

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

少なくとも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'

関数のバイトコードを分解すると、名前も壊れていることがわかります。

>>> 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年以降同じです。

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

于 2012-09-21T20:44:12.300 に答える