如何在Python中分离子方法和父方法?

2024-10-01 17:35:10 发布

您现在位置:Python中文网/ 问答频道 /正文

当为父类设置的属性顺序在子类中中断时,我试图找到使用继承的正确方法。下面是一个例子:

class Car:
    def __init__(self, efficiency, tank_size) -> None:
        self.efficiency = efficiency
        self.tank_size = tank_size
        self.range = self.calc_range()

    def calc_range(self):
        return self.efficiency * self.tank_size


class HybridCar(Car):
    def __init__(self, efficiency, tank_size, battery_capacity) -> None:
        super().__init__(efficiency, tank_size)
        self.battery_range = self.calc_battery_range()
        self.battery_capacity = battery_capacity

    def calc_range(self):
        return self.efficiency * self.tank_size + self.battery_range

    def calc_battery_range(self):
        return self.battery_capacity * self.efficiency

我想HybridCar调用Car__init__方法,但我无法让它工作。我无法在HybridCar中调用self.calc_range(),因为我没有定义self.battery_range。我不能定义self.battery_range,因为它依赖于self.efficiency,我还没有定义。我能看到的唯一方法是HybridCar不调用Car__init__方法,而是使用所有相同的代码。我想避免这种情况,因为__init__方法中有很多代码(真正的类所做的远不止这些),而且有很多重复的代码(pylint警告我不要调用^{)。解决这个问题的正确方法是什么


Tags: 方法selfsizereturn定义initdefcalc
2条回答

以下内容对您有帮助吗

class Car:
    def __init__(self, efficiency, tank_size) -> None:
        self.efficiency = efficiency
        self.tank_size = tank_size
        self.range = self.calc_range_Car()

    def calc_range_Car(self):
        return self.efficiency * self.tank_size


class HybridCar(Car):
    def __init__(self, battery_capacity, car) -> None:
        super().__init__(car.efficiency, car.tank_size)
        self.battery_capacity = battery_capacity
        self.battery_range = self.calc_battery_range()

    def calc_range_Hybrid(self):
        return self.efficiency * self.tank_size + self.battery_range

    def calc_battery_range(self):
        return self.battery_capacity * self.efficiency

parent = Car(2, 5)
child = HybridCar(10, parent)
print(child.calc_range_Car())
print(parent.range)

唯一不同的是,我将Car对象命名为HybridCar构造函数,并将方法calc_range重命名为calc_range_Carcalc_range_Hybrid。我理解这可能并不理想,因为在子类中重写超类方法非常有用。 输出

10
10

我认为您希望在类中使用^{}定义。这意味着self.range = self.calc_range()函数的赋值实际上不会在__init__()期间执行。但是,每次尝试获取range属性时,都会运行self.calc_range()

您还提到有很多潜在的重复代码,因此在下面的示例中,我已经包括了^{} (Abstract Base Class)概念的使用。当您继承了共享同名方法但具有不同实现的类时,这是一个非常方便的概念

import abc


class CarABC(abc.ABC):
    def __init__(self, efficiency, tank_size) -> None:
        self.efficiency = efficiency
        self.tank_size = tank_size

    @abc.abstractmethod
    def calc_range(self):
        pass

    @property
    def range(self):
        return self.calc_range()


class Car(CarABC):
    def calc_range(self):
        return self.efficiency * self.tank_size


class HybridCar(CarABC):
    def __init__(self, efficiency, tank_size, battery_capacity) -> None:
        super().__init__(efficiency, tank_size)
        self.battery_capacity = battery_capacity

    @property
    def battery_range(self):
        return self.calc_battery_range()

    def calc_range(self):
        return self.efficiency * self.tank_size + self.battery_range

    def calc_battery_range(self):
        return self.battery_capacity * self.efficiency

if __name__ == "__main__":
    c = Car(0.8, 100)
    hc = HybridCar(0.8, 100, 120)
    print(c.range)

相关问题 更多 >

    热门问题