2

このコードがあります:

class A:
  __x = 2

  def f(self):
    print(dir(self)) # there is attribute _A__x, but not __x
    print(self.__x) # prints 2
    print(self._A__x) # prints 2

x = A()
x.f()
print(x.__x) # AttributeError: 'A' object has no attribute '__x'

__x変数へのアクセスは、このメソッドのようなメソッド内では許可されているself.__xが、このメソッドの外では許可されていないのはなぜですか? アンダースコアが 2 つある名前が壊れていることは知っていますが、問題は、self属性として壊れたバージョンしかないのに、この壊れていないバージョンがメソッド内で機能するように何が特別なのかということです。

編集:

_A__nameたとえば、フォームの名前でクラスに属性が追加されていることに気付きました。

class A:
  _A__y = 3

  def f(self):
    print(self.__y) # prints 3
    print(self._A__y) # prints 3

x = A()
x.f()

次に、クラス内では、たとえばインタープリターが変数__yを検索するときに名前も使用できるように見えるため_A__y、プレフィックス_Aは C++ のスコープ解決のように機能するようA::です。しかし、それがどのように機能するかについての詳細はわかりません。

したがって、元の質問を拡張できます。なぜこの場合、 altough のみが定義さself.__yれているのと同じ効果があるのですか?self._A__y_A__y

4

2 に答える 2

4

先頭に 2 つのアンダースコアが付いた名前の属性は、クラス外で使用するために「非表示」になっています (実際には以下を参照してください)。他の言語のプライベート属性と似たようなものです。

重要なことは、クラスの外部から属性にアクセスすることはできませんx.__xが、. クラス内では、(例で示したように)両方の方法で使用できます。x._A__x

__xC++ などの他の言語では、 yourを private として宣言し、クラス内で使用することはできますが、クラス__x外で使用することはできません。pythonでも同様です。内部でも__x外部でも使用するため、使用しないでください。

この動作のドキュメントについては、こちらを参照してください。

于 2013-05-25T12:06:11.917 に答える
1

self.__xマングルされて に変換されるためself._A__x、機能します。マングリングは、クラス定義内のコードでのみ行われます。

于 2013-05-25T12:08:30.103 に答える