Theo Theo - 2 months ago 9
Python Question

Python - Override parent class argument

I have a super class and a sub class.

class Vehicle:
def __init__(self, new_fuel, new_position):
self.fuel = new_fuel
self.position = new_position

class Car(Vehicle):
# Here, I am stating that when Car is initialized, the position will be
# at (0, 0), so when you call it, you do not have to give it a new_position argument
def __init__(self, new_fuel, new_position=(0, 0)):
super(Car, self).__init__(new_fuel, new_position)
self.new_position = new_position


Problem:

I want this to initialize a Car object with 10 fuel and position of (0, 0)
but I don't want to put in an argument for new_position because I've stated that when all cars are initialized, they have a position of (0, 0). Also, I don't want to change any arguments in the parent class (vehicle), I just want to override them within the sub classes (such as Car).

test_car = Car(10)
print(test_car.new_position)
>>> (0,0)


However, it keeps giving me this error and asks to put in an argument for new_position

TypeError: __init__() missing 1 required positional argument: 'new_position'

Answer

As far as I understand what you are trying to achieve, just simply delete the "new_position" parameter from your Car __init__ method.

class Vehicle:
   def __init__(self, new_fuel, new_position):
        self.fuel = new_fuel
        self.position = new_position

class Car(Vehicle):
   # Here, I am stating that when Car is initialized, the position will be 
   # at (0, 0), so when you call it, you do not have to give it a new_position argument 
    def __init__(self, new_fuel):
        super(Car, self).__init__(new_fuel, new_position= (0, 0))

Later when any method from the Car class will need a "position" argument, it will search inside the Car class and when not found, it will jump into Vehicle and will find it.

Lets say that you've implemented get_position() method in your Vehicle class.

class Vehicle:
    <everything as always>

    def get_position(self):
        return self.position

class Car(Vehicle):
   <everything as always>

a = Car(10)
a.get_position() # Returns (0, 0)

Edit to comment:

class Vehicle:
    def __init__(self, new_fuel):
        self.fuel = new_fuel

    def get_position(self):
        return self.__class__.POSITION

class Car(Vehicle):
    POSITION = (0, 0)
    # Here, I am stating that when Car is initialized, the position will be 
    # at (0, 0), so when you call it, you do not have to give it a new_position argument 
    def __init__(self, new_fuel):
       super(Car, self).__init__(new_fuel)

    def new_position(self, value):
       self.__class__.POSITION = value

a = Car(10)
b = Car(20)
c = Car(30)

for each in [a, b, c]:
    print(each.get_position())
(0, 0)
(0, 0)
(0, 0)
c.new_position((0, 1))
for each in [a, b, c]:
    print(each.get_position()) 
(0, 1)
(0, 1)
(0, 1)
Comments