【问题标题】:How to use Instance as Attributes?如何使用实例作为属性?
【发布时间】:2017-09-24 15:04:56
【问题描述】:

让我举一个简单的例子:

如果我想使用Tank 类实例作为汽车的属性。同时,我希望tank_info方法,根据Car类中的不同型号,给出不同的坦克尺寸。

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()

假设奥迪有 A4、A6 和 A8,它们的油箱尺寸分别为 20、25、30。 我应该如何编写tank_info 方法,让它自动判断它的水箱尺寸?

【问题讨论】:

  • 您是要硬编码不同型号的油箱尺寸,还是要将尺寸作为Car.__init__ 的附加参数传递?
  • 使用字典将汽车映射到油箱尺寸。

标签: python class


【解决方案1】:

您可以接受 tank_size 参数到 Car

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

现在你的例子

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

会输出

The car is Audi A4
The tank size is 20 gallons

【讨论】:

  • 但是我在这里想要的是避免自己输入tank_size。相反,我希望 tank_info 方法仅根据汽车型号自动给出不同的坦克尺寸。简单来说就是把self.model链接到tank_size,然后创建一个关系,或者一个字典出来?
【解决方案2】:

您必须在实例中存储水箱大小。因此,当您创建 Tank 对象时,您也可以指定大小。这是您创建汽车油箱并因此创建新尺寸的地方。

        self.tank = Tank(tank_size)

以前是

        self.tank = Tank()

这会调用

class Tank():
    def __init__(self, tank_size=20):
        self.tank_size = tank_size

由于您没有通过tank_size,因此默认情况下所有汽车都分配了20尺寸,这是由于tank_size=20而发生的。


sizes={
        'Audi': {
                 'A4':25,
                 'A6':30,
                 'A8':35
                },
        'BMW':  {
                 'Series 3':1,
                 'Series 6':2
                }
}

class Car():
    def __init__(self, make, model, tank_size):
        global sizes
        self.make = make
        self.model = model
        self.tank = Tank(sizes[make][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=20):
        self.tank_size = tank_size
    def tank_info(self):
        print('The tank size is', self.tank_size, 'gallons')

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

【讨论】:

  • 但是我在这里想要的是避免自己输入tank_size。相反,我希望 tank_info 方法仅根据汽车型号自动给出不同的坦克尺寸。简单来说,就是把self.model链接到tank_size,并创建一个关系,或者从中创建一个字典?
  • 固定有字典
【解决方案3】:

您可以通过将油箱尺寸映射封装在单独的字典中来避免输入油箱尺寸。

以下示例显示了如何动态构建逻辑。汽车油箱尺寸封装在油箱尺寸字典的字典中,其中外键表示型号,内键表示品牌。如果您想添加更多车型或品牌,只需将它们添加到 car_tank_sizes 字典即可。

另请注意,如果未指定水箱尺寸,则默认为 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()

下面的替代方法展示了如何在 Tank 本身内封装容器尺寸。

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()

【讨论】:

  • 所以最终,这个字典必须在 Car 类中,而不是在 Tank 类中。是否可以在 Tank 类中以某种方式编写,因为这样似乎更有条理。
  • 您可以将字典移至 Tank,然后在 Car 中将其称为 Tank。汽车油箱尺寸。或者,整个逻辑可以在 Tank 的 init 方法中。
  • 因为这个想法是让所有与 Tank 信息相关的东西都独立于 Car 类。否则,我可以在 Car 类中轻松设置它,而不必拥有 Tank 类
  • 在这种情况下,Tank 需要知道汽车的品牌和型号。您可以将品牌和型号传递给 Tank 的 init 方法。我已经用替代方法更新了上述答案。
  • 谢谢!你太棒了!!!这个问题从昨晚就一直困扰着我,不知道怎么做就睡不着!
猜你喜欢
  • 2013-11-18
  • 2022-01-18
  • 1970-01-01
  • 2020-06-13
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
  • 2016-04-06
  • 1970-01-01
相关资源
最近更新 更多