Code_Control_jxie0755 Code_Control_jxie0755 - 23 days ago 9
Python Question

How to use Instance as Attributes?

Let me show a quick example:

If I want to use

Tank
Class instance as the car's attribute. At the same time, I want the method
tank_info
, to give different tank size, according to different model in the
Car
class.

class Car():
def __init__(self, make, model):
self.make = make
self.model = model
self.tank = Tank()

def get_car_info(self):
long_name = self.make + ' ' + self.model
print('The car is', long_name)

class Tank():
def __init__(self, tank_size=20):
self.tank_size = tank_size
def tank_info(self):
print('The tank size is', self.tank_size, 'gallons')

my_car = Car('Audi', 'A4')
my_car.get_car_info()
my_car.tank.tank_info()


Let's say, Audi has A4, A6, and A8, their tank size are 20, 25, 30.
How should I write the
tank_info
method, for it to automatically tell what tank size it has?

Answer Source

You can avoid the input of tank size by encapsulating the tank size mapping in a separate dictionary.

The following example shows how you can build the logic dynamically. The car tank size is encapsulated in a dictionary of tank size dictionary where the outer key represents the model and the inner key represents the make. If you want to add more car models or makes, you just need to add them to the car_tank_sizes dictionary.

Also note that if tank sizes are not specified, it defaults to 20.

class Car():
    car_tank_sizes = {'Audi': {'A4': '20', 'A6': 25, 'A8': 30}}

    def __init__(self, make, model):
        self.make = make
        self.model = model
        self.tank = Tank(Car.car_tank_sizes.get(self.make,{}).get(self.model))

    def get_car_info(self):
        long_name = self.make + ' ' + self.model
        print('The car is', long_name)


class Tank():
    def __init__(self, tank_size):
        if (tank_size is None):
            self.tank_size = 20
        else:
            self.tank_size = tank_size

    def tank_info(self):
        print('The tank size is', self.tank_size, 'gallons')


my_car = Car('Audi', 'A6')
my_car.get_car_info()
my_car.tank.tank_info()

The following alternate approach shows how to encapsulate tank size inside Tank itself.

class Car():
    def __init__(self, make, model):
        self.make = make
        self.model = model
        self.tank = Tank(self.make, self.model)

    def get_car_info(self):
        long_name = self.make + ' ' + self.model
        print('The car is', long_name)


class Tank():
    car_tank_sizes = {'Audi': {'A4': '20', 'A6': 25, 'A8': 30}}

    def __init__(self, make, model):
        self.tank_size = Tank.car_tank_sizes.get(make, {}).get(model, 20)

    def tank_info(self):
        print('The tank size is', self.tank_size, 'gallons')


my_car = Car('Audi', 'A4')
my_car.get_car_info()
my_car.tank.tank_info()