首页 > 解决方案 > 错误是 exec(compile(f.read(), filename, 'exec'), namespace) 。第 26 行 ---- def__init__(self, battery_size = 70):

问题描述

我不明白def__init__(self, battery_size = 70):这段代码的第 26 行有什么问题。我正面临来自exec(compile(f.read(), filename, 'exec'), namespace).

class Car():
    def __init__(self, make, model, year):
        self.make = make
        self.model = model
        self.year = year
        self.odometer_reading = 0

    def get_descriptive_name(self):
        long_name = str(self.year) + ' ' + self.make + ' ' + self.model
        return long_name.title()

    def read_odometer(self):
        print("This car has" + str(self.odometer_reading) + "miles on it.")

    def update_odometer(self, mileage):
        if mileage >= self.odometer_readings:
            self.odometer_reading = mileage
        else:
            print("You can't roll back an odometer!")

    def increment_odometer(self, miles):
        self.odometer_reading += miles


class Battery():
    def__init__(self, battery_size = 70):
        self.battery_size = battery_size
    def describe_battery(self):
        print("This car has a " + str(self.battery_size) + "-kWh battery." )

class ElectricCar(Car):
    def __init__(self, make, model, year):
        super().__init__(make, model, year)
        self.battery_size = Battery()



my_tesla = ElectricCar('tesla', 'model s', 2016)
print(my_tesla.get_descriptive_name())
my_tesla.describe_battery()

用于此的输出将是

2016 Tesla Model S # from .get_descriptive_name()
This car has a 70-kWh battery. # from .describe_batttery()

标签: pythonpython-3.x

解决方案


除了def __init__错字之外,您的错误是对象层次结构的问题,正如您可能已经想到的那样。

解释

ElectricCar接收一个Battery对象作为属性,即battery_size

class ElectricCar(Car):
    def __init__(self, make, model, year):
        super().__init__(make, model, year)
        self.battery_size = Battery()

你把describe_battery作为Battery类的属性,所以调用my_tesla.describe_battery永远不会工作,因为my_tesla不是Battery.

可维护性是 Pythonic 生态系统的主要焦点之一。考虑到这一点,下面将解决您的编译问题,然后改进您插入字符串的方式。

可维护的解决方案

有很多方法可以使您的代码工作- 并非所有方法都最好维护。对代码进行微小更改的显着改进示例:

my_tesla.battery.describe()

“内” describe_batterymy_tesla

这种方式清楚地显示了您正在构建的层次结构,同时简洁易读。此外,所需的更改很少。

让我们在这里看看如何做到这一点。中ElectricCar.__init__,更改battery_sizebattery

self.battery = Battery()

在 内Battery,切换describe_battery到 just describe- 从而避免冗余。

class Battery():
    ...
    def describe(self):
        ...

现在创建特斯拉并打印它的电池就像

my_tesla = ElectricCar('tesla', 'model s', 2016)
my_tesla.battery.describe()

可读性:字符串插值

您有几个地方可以在这​​里插入不同的字符串,并且它的完成方式可能更具可读性 - 甚至是规范的。举get_descriptive_name个例子:

def get_descriptive_name(self):
    long_name = str(self.year) + ' ' + self.make + ' ' + self.model
    return long_name.title()

在 的帮助下.format,您可以以

def get_descriptive_name():
    return '{} {} {}'.format(self.year, self.make, self.model)

我个人最喜欢的:从 python 3.6 开始,你可以使用 f-strings,它是最小的并且可以说更具可读性:

def get_descriptive_name():
    return f'{self.year} {self.make} {self.model}'

这最终可以应用于您在此处执行的每个插值 - read_odometerdescribe方法和get_descriptive_name。就性能而言,所有这些都非常相似,所以这大约是 60% 的偏好问题。


推荐阅读