Access to mangled name within function works, but outside function not
<p>There is this code:</p>

<pre><code>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'
</code></pre>

<p>Why access to <code>__x</code> variable is allowed inside method like <code>self.__x</code> but not outside this method? I know that name with two underscores is mangled, but the question is what is special so that this unmangled version works inside the method altough <code>self</code> has only mangled version as attribute.</p>

<p>Edit:</p>

<p>I noticed that if some attribute is added to the class with name of form <code>_A__name</code> for example:</p>

<pre><code>class A:
  _A__y = 3

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

x = A()
x.f()
</code></pre>

<p>then inside class it seems that when for example interpreter looks for variable <code>__y</code> he can take also <code>_A__y</code> name, so it seems that prefix <code>_A</code> works something similar like scope resolution in C++ like <code>A::</code>. But I am not sure about details how it works.</p>

<p>So the original question can be extended why in this case <code>self.__y</code> has the same effect as <code>self._A__y</code> altough only <code>_A__y</code> is defined?</p>
