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.
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
).
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With