Как создать экземпляр класса с экземпляром другого класса в качестве атрибута? - PullRequest
0 голосов
/ 12 января 2020

Я пытаюсь выучить Python самостоятельно. У меня есть фрагмент кода:

class Car():

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


class Tank():

    def __init__(self, *args, **kwargs):
        self.tank_size = kwargs.get('tank_size', None)

    def describe_tank(self):
        print("This car has a " + str(self.tank_size) + "-L tank.")

Можно ли создать экземпляр Car без указания значения по умолчанию для параметра tank_size в __init__ класса Tank? Спасибо. PS Немного отредактировал код, чтобы сделать его более логичным.

Ответы [ 3 ]

3 голосов
/ 12 января 2020

Я думаю, что вы можете попробовать получить к нему доступ с помощью kwargs.get и указать там значение по умолчанию.

    def __init__(self, *args, **kwargs):
        self.tank_size = kwargs.get('tank_size', None)

Так что теперь вы можете передать tank_size конструктору Car и далее конструктору Tank. Если вы все еще не хотите использовать значение по умолчанию, вы можете снова передать его через kwargs.

    def __init__(self, make, model, year, **kwargs):
        self.make = make
        self.model = model
        self.year = year

        self.tank = Tank(**kwargs)

Так что это будет похоже на

class Car():
    def __init__(self, make, model, year, **kwargs):
        self.make = make
        self.model = model
        self.year = year

        self.tank = Tank(**kwargs)

class Tank():
    def __init__(self, *args, **kwargs):
        self.tank_size = kwargs.get('tank_size', None)

    def describe_tank(self):
        if self.tank_size:
            print("This car has a " + str(self.tank_size) + "-L tank.")
        else:
            print("No info about the tank.")



car = Car("bmw", "m5", 2000)
car.tank.describe_tank()

new_car = Car("bmw", "m5", 2000, tank_size=3)
new_car.tank.describe_tank()
0 голосов
/ 12 января 2020

Вы всегда можете сохранить его как атрибут и удалить его из параметров инициализации.

class Car():

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


class Tank():

    def __init__(self):
        self.tank_size = None

    def set_tank_size(self, size):
        self.tank_size = size

    def describe_battery(self):
        print("This car has a " + str(self.tank_size) + "-L tank.")

Или, если вы хотите сделать это правильно, вы можете использовать свойство и установщик.

from number import Real


class Car():

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


class Tank():

    def __init__(self):
        self._tank_size = None

    @property
    def tank_size(self):
        return self._tank_size

    @tank_size.setter
    def tank_size(self, size):
        if not isinstance(size, Real):
            raise TypeError('Tank `size` must be a number.')
        if not size >= 0:
            raise ValueError('Tank `size` must be >= 0.') # electrics have a 0-L tank?
        self._tank_size = size

    def describe_battery(self):
        print("This car has a " + str(self.tank_size) + "-L tank.")
0 голосов
/ 12 января 2020

Вы можете попробовать это, но это решение ограничит вас в расширении ввода класса Tank, вам придется вручную обрабатывать все дополнительные атрибуты в будущем.

class Tank():
    def __init__(self, *args,**kwargs):
        if args:           
            self.tank_size = args[0]
        else:
            self.tank_size = "Not Specified"

    def describe_battery(self):
        print("This car has a {}-L tank.".format(self.tank_size))

Также для форматирования строки я бы рекомендуем встроенную функцию .format.

...