title: python name mangling in __init__ seems inconsistent
body: <p>I'm trying to use a subclass that enhances instead of overriding the base class. I'm using the <code>super</code> method to call the base class. I find that I need to use the name mangling feature in <code>__init__</code> (but only in init?) to make the code work. So for the heck of it I made the this print example. Since I didn't use name mangling I expected it to call subclass twice when I did the init, instead it calls the base class </p>
  
  <p>It seems that <code>__init__</code> sometimes sees the base class and sometimes sees the subclass. I'm sure it's just an incomplete understanding on my part, but was do I need name mangling for the real code, when in the print example it calls the base and subclass just fine?</p>
  
  <p>the code</p>
  
  <pre><code>class base:
      def __init__(self):
          self.print()
  
      def print(self):
          print("base")
  
  class subclass(base):
      def __init__(self):
          super(subclass, self).__init__()
          self.print()
  
      def print(self):
          super(subclass, self).print()
          print("subclass")
  
  x = base()
  x.print()
  print("--")
  y = subclass()
  y.print()
  </code></pre>
  
  <p>the output - why doesn't <code>y = subclass()</code> print <code>subclass</code> instead of <code>base</code> since I didn't use name mangling?</p>
  
  <pre><code>&gt; ./y.py 
  base
  base
  -- 
  base
  subclass
  base
  subclass
  base  
  subclass
  </code></pre>
  
  <p>broken code when I don't use name mangling, works when I use <code>self.__set</code> and <code>__set = set</code> (the commented code). It gets the following error when I don't use <code>__set</code>:</p>
  
  <pre><code>File "./x.py", line 5, in __init__
     self.set(arg)
  TypeError: set() missing 1 required positional argument: 'arg2'
  </code></pre>
  
  <p>the code:</p>
  
  <pre><code>class base:
      def __init__(self, arg):
          self.set(arg)
          # self.__set(arg)
  
      # __set = set
  
      def set(self, arg):
          self.arg = arg
  
      def print(self):
          print("base",self.arg)
  
  class subclass(base):
      def __init__(self, arg1, arg2):
          super(subclass, self).__init__(arg1)
          self.set(arg1, arg2)
  
      def set(self, arg1, arg2):
          super(subclass, self).set(arg1)
          self.arg2 = arg2
  
      def print(self):
          super(subclass, self).print()
          print("subclass", self.arg2, self.arg)
  
  x = base(1)
  
  x.print()
  x.set(11)
  x.print()
  
  y = subclass(2,3)
  
  y.print()
  y.set(4,5)
  y.print()
  </code></pre>
  
  <p>======= update =======</p>
  
  <p>I rewrote the code to look like this:</p>
  
  <pre><code>class base:
      def __init__(self):
          print("base init")
          self.print()
  
      def print(self):
          print("base print")
  
  class subclass(base):
      def __init__(self):
          print("sc init")
          super(subclass, self).__init__()
          print("sc after super")
          self.print()
  
      def print(self):
          print("subclass print start")
          super(subclass, self).print()
          print("subclass print")
  
  y = subclass()
  print("--")
  y.print()
  </code></pre>
  
  <p>when I run I get this output:</p>
  
  <pre><code>sc init
  base init
  subclass print start &lt;&lt;&lt;&lt; why is the subclass print called here
  base print
  subclass print
  sc after super
  subclass print start
  base print
  subclass print
  --
  subclass print start
  base print
  subclass print
  </code></pre>
  
  <p>why does the <code>self.print</code> in the base init call the subclass print when I'm initing the subclass? I was expecting that to call the base print. it does call the base print when I call it outside of the init.</p>