Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the child class does not inherit the method from parent class in python in this example?

I have the following code.

class Foo(object):
     def __init__(self):
         self.__baz = 40
     def foo(self):
         print self.__baz

class Bar(Foo):
     def __init__(self):
         #super(Bar, self).__init__()
         self.__baz = 21
     def bar(self):
         print self.__baz

x = Bar()
x.foo()
x.bar()

I get this error:

Traceback (most recent call last):
  File "classes.py", line 15, in <module>
    x.foo()
  File "classes.py", line 5, in foo
    print self.__baz
AttributeError: 'Bar' object has no attribute '_Foo__baz'

why is the foo method not inherited in Bar.

EDIT: It works fine, if you call super which is commented out.

like image 790
brain storm Avatar asked Sep 27 '13 04:09

brain storm


2 Answers

The double underscore attributes have their names mangled based on the current/containing namespace. In the function foo, the current namespace is Foo so when python looks up self.__baz, it will actually look for self._Foo__baz due to the name mangling scheme. Since nowhere in Foo have you actually set an __baz attribute, the class has no _Foo__baz attribute (it has a _Bar__baz attribute since you set self.__baz in a method within Bar).

Of course, as you've probably noticed, if you call Foo.__init__(self) in Baz.__init__ (directly or via super), you'll see the problem go away because Foo.__init__ sets __baz (i.e. _Foo__baz).

like image 198
mgilson Avatar answered Sep 19 '22 15:09

mgilson


Since python 3.6, we can now use the __init_subclass__ function, which is called automatically before __init__ of the Child.

class Foo(object):
     def __init_subclass__(self):
         self.__baz = 40
     def foo(self):
         print(self.__baz)

class Bar(Foo):
     def __init__(self):
         self.__baz = 21
     def bar(self):
         print(self.__baz)

x = Bar()
x.foo()
x.bar()

output

40
21
like image 24
kruserr Avatar answered Sep 23 '22 15:09

kruserr