title: Why is `self.__x` not working but `self.y` is?
body: <p>I am learning to use <code>@property</code> decorators. I have the following two code snippets:</p>
  <h2>Code 1</h2>
  <pre><code>class P2:
      def __init__(self, x):
          self.x = x
      @property
      def x(self):
          return self.y
      @x.setter
      def x(self, x):
          if x &lt; 0:
              self.y = x
          elif x &gt; 1000:
              self.y = 1000
          else:
              self.y = x
     
  p1 = P2(7600)
  print(p1.y)
  </code></pre>
  <h2>Code2</h2>
  <pre><code>class P2:
      def __init__(self, x):
          self.x = x
      @property
      def x(self):
          return self.__x
      @x.setter
      def x(self, x):
          if x &lt; 0:
              self.__x = x
          elif x &gt; 1000:
              self.__x = 1000
          else:
              self.__x = x
     
  p1 = P2(7600)
  print(p1.__x)
  </code></pre>
  <p>To obtain the code2 I replace <code>y</code> by <code>__x</code> in code1. But the issue is that the code1 is running perfectly fine but the code2 is giving an error <code>'P2' object has no attribute '__x'</code>.</p>
  <p>My understanding is that <code>y</code> and <code>__x</code> are merely two variables, they should behave in the same way, so in my opinion code2 and code1 are identical and both should give same output.</p>
  <p>But, it is not happening. What is wrong in my understanding?</p>