0

Why this works

class A():
   def __init__(self):
       self.B = self.__B__()
    
   class __B__():
       def __init__(self):
           pass
       def speak(self):
           print("Hi, I'm B")
            
   def speak(self):
       print("Hi, I'm A")

And this works:

class A():
    def __init__(self):
        super(A, self).__init__()
            
    def speak(self):
        print("Hi, I'm A")

But this doesn't?

class A():
    def __init__(self):
        super(A,self).__init__()
        self.B = self.__B__()
    
    class __B__():
        def __init__(self):
            super(__B__,self).__init__()
        def speak(self):
            print("Hi, I'm B")
            
    def speak(self):
        print("Hi, I'm A")

And I get the message that __B__ does not exists. Also, what does super(ClassName,self).__init__() do and why should/shouldn't use it?

  • 2
    `__B__` doesn't exit. `A.__B__` does, but it's not at all clear what you are asking beyond that or why you are doing this. – Mark Jul 12 '20 at 00:41
  • Please ask only one question per question. To get the second question out of the way, see here: https://stackoverflow.com/questions/576169/understanding-python-super-with-init-methods – mkrieger1 Jul 12 '20 at 00:41
  • @MarkMeyer what I'm trying to understand is why the two first examples works, but the 3rd one throws the error saying that __B__ does not exist. Why removing the "super(__B__,self).__init__()" works? – Pedro Pablo Severin Honorato Jul 12 '20 at 01:02
  • @mkrieger1 Thank you. I already saw that link and I "understood" what was happening there, but I don't get it why it doesn't work when I put B inside A – Pedro Pablo Severin Honorato Jul 12 '20 at 01:23
  • 2
    In the first example, `self.__B__` finds `__B__` on the class after not finding it on the instance. That's different that just `__B__`. There is no name in scope called `__B__`. – Mark Jul 12 '20 at 01:25
  • 1
    This has nothing to do with `super`, really. It is simple, `__B__` **isn't in scope** where you are trying to use it. You must use `A.__B__`. This nested class structure makes very little practical sense. Why are you doing things this way? Why isn't `class B` just in the global scope? Why are you using two underscores like this? – juanpa.arrivillaga Jul 12 '20 at 01:33
  • @MarkMeyer were correct with the A.__B__ thing (sorry Mark, didn't understood it at first glance). – Pedro Pablo Severin Honorato Jul 12 '20 at 01:51
  • @juanpa.arrivillaga why I am using __ is not really important (I think?) because the class could be named "enchilada" and the result would still be A.enchilada in order to work. Now, what I'm missing is when all this "super" thing is really needed. Oh and I want to do it with inner classes because I don't want that the class __B__ can be accessed from anywhere else than A. Is this wrong? Does the __ affects in some way? I mean, I know that _ and __ are used to declare private stuffs (I don't remember veeeery well...I'm still learning OOP, so excuse me for my noob questions) – Pedro Pablo Severin Honorato Jul 12 '20 at 01:54
  • Python doesn't have private variables. A single underscore denotes a part of the non public API, but it is still accesible. And nested classes do not prevent access outside of A. Again, it doesn't make any sense. You use `super` when you need to call the next class in the method resolution order. It doesn't make any sense in the context you are using it currently. – juanpa.arrivillaga Jul 12 '20 at 04:08

0 Answers0