Why this simple code doesn't work for Python 2.7 ? Please, help. Most likely I misuse super method in 'New Style' for classes.
class Mechanism(object):
def __init__(self):
print('Init Mechanism')
self.__mechanism = 'this is mechanism'
def get_mechanism(self):
return self.__mechanism
class Vehicle(object):
def __init__(self):
print('Init Vehicle')
self.__vehicle = 'this is vehicle'
def get_vehicle(self):
return self.__vehicle
class Car(Mechanism, Vehicle):
def __init__(self):
super(Car, self).__init__()
c = Car()
print(c.get_mechanism())
print(c.get_vehicle())
The error:
Init Vehicle
Traceback (most recent call last):
File "check_inheritance.py", line 22, in <module>
print(c.get_mechanism())
File "check_inheritance.py", line 7, in get_mechanism
return self.__mechanism
AttributeError: 'Car' object has no attribute '_Mechanism__mechanism'
EDIT
- Fixed
def __init(self):inMechanismclass ontodef __init__(self): - The correct answer is to use
supermethod in all classes. Not only inCarclass. See the answer of Martijn Pieters - Try to avoid double underscore
__for private variables. It is not a Python way (style of code). See the discussion for more info here.
1 Answer 1
You have 2 issues:
You misnamed the
__init__method ofMechanism; you are missing two underscores.Your
__init__methods do not cooperate correctly in a multiple inheritance situation. Make sure you always callsuper(...).__init__(), in all your__init__methods.
The following code works:
class Mechanism(object):
def __init__(self):
super(Mechanism, self).__init__()
print('Init Mechanism')
self.__mechanism = 'this is mechanism'
def get_mechanism(self):
return self.__mechanism
class Vehicle(object):
def __init__(self):
super(Vehicle, self).__init__()
print('Init Vehicle')
self.__vehicle = 'this is vehicle'
def get_vehicle(self):
return self.__vehicle
class Car(Mechanism, Vehicle):
def __init__(self):
super(Car, self).__init__()
Demo:
>>> c = Car()
Init Vehicle
Init Mechanism
>>> print(c.get_mechanism())
this is mechanism
>>> print(c.get_vehicle())
this is vehicle
You should probably also not use double-underscore names. See Inheritance of private and protected methods in Python for the details, but the short reason is that you do not have a use case here for class-private names, as you are not building a framework meant to be extended by third parties; that's the only real usecase for such names.
Stick to single-underscore names instead, so _mechanism and _vehicle.
10 Comments
super(...).__init__() in ALL classes. Thank you, Martijn! Your change is working.c.get_mechanism(), just use c.mechanism (a public attribute).property object (the Pythonic getter-setter pattern) is trivial, so you never have to worry about that future choice.Explore related questions
See similar questions with these tags.
superhere: as currently structured, theVehicle.__init__method won't get called. You need a common root class (a base class for bothVehicleandMechanism), and all subclasses, includingVehicleandMechanismshould callsuper.__init__method.__init__method in the chain, so the initializer forMechanismis not called for two separate reasons. You really should not be using leading-double-underscore attributes unless you are building a framework for 3rd-parties to extend on, see Inheritance of private and protected methods in Pythonsuperin all child classes for co-operative multi-inheritance to work properly. Then the private variables will work just fine.