There are two problems here:
- Python objects have one dict for storing attributes, there can be no attribute hiding like in other programming languages
- You are incorrectly using multiple inheritance and
super
.
Python will not work how you want it to work. Each instance in Python has one shared dict which all classes share for attribute access. This means you cannot hide an attribute, only overwrite it. To do what you want you must a unique name for model in Car
and a unique name in Jeep
. eg. car_model
and jeep_model
. A quick test that shows this:
class Parent(object):
def __init__(self):
super(Parent, self).__init__()
self.value = "parent"
def parent_value(self):
return self.value
class Child(Parent):
def __init__(self):
super(Child, self).__init__()
self.value = "child"
def child_value(self):
return self.value
p = Parent()
assert p.parent_value() == "parent"
c = Child()
assert c.child_value() == "child"
assert c.parent_value() == "child"
You could use "private" variables. These aren't really private, python just does something called name mangling to make them harder to accidentally overwrite.
class Parent(object):
def __init__(self):
super(Parent, self).__init__()
self.__value = "parent"
def parent_value(self):
return self.__value
class Child(Parent):
def __init__(self):
super(Child, self).__init__()
self.__value = "child"
def child_value(self):
return self.__value
p = Parent()
assert p.parent_value() == "parent"
c = Child()
assert c.child_value() == "child"
assert c.parent_value() == "parent"
print(vars(c))
# prints {'_Child__value': 'child', '_Parent__value': 'parent'}
c._Parent__value = "new value"
assert c.parent_value() == "new value"
Finally, your __init__
methods in your base classes do not make a call to super. In non-multiple inheritance this is not necessary for the base class. However, in your case (which uses multiple inheritance) the set of __init__
methods will get to Car.__init__
and then stop without calling Jeep.__init__
.
class Car(object):
def __init__(self):
print("init car")
super(Car, self).__init__()
print("assigning car")
self.car = "car"
class Jeep(object):
def __init__(self):
print("init jeep")
super(Jeep, self).__init__()
print("assigning jeep")
self.jeep = "jeep"
class ElectricCar(Car, Jeep):
def __init__(self):
print("init electric car")
super(ElectricCar, self).__init__()
print("assigning electric")
self.electric = "electric"
car = ElectricCar()
# prints the following:
# init electric car
# init car
# init jeep
# assigning jeep
# assigning car
# assigning electric