使用子类覆盖分配给父类中评估方法的变量

问题描述 投票:0回答:1

我是面向对象编程的新手。我有一个父类,在其构造函数中我有一个变量(在下面的示例中为

bmi
),该变量需要对同一类的方法(
bod_mass_idx
)进行评估(我这样做是因为此方法需要时间来评估并且是被同一个类中的后续方法多次使用,所以我不想每次使用它时都计算它)。

我正在尝试构造一个子类,该子类覆盖存储我在父类中定义的计算昂贵的方法的变量。当然,我的实际示例比这复杂得多,但这个示例总结了基本细节。

class Human:
    def __init__(self, height, weight):
        self.height = height
        self.weight = weight
        self.prefactor = 1.0
        self.bmi = self.bod_mass_idx()
        
    def bod_mass_idx(self):
        return self.prefactor * self.weight/self.height**2
    
class MetaHuman(Human):
    def __init__(self, height, weight, fraction):
        super().__init__(height, weight)
        self.prefactor = fraction

这里,我想要用

fraction
中定义的值
MetaHuman
来替换
prefactor
中的
Human
。但是当我初始化子类并尝试评估
bmi
方法时,我没有得到更新的值:

hum = Human(2,100)
m_hum = MetaHuman(2,100,0.5)

print(m_hum.bmi()) #25.0
print(hum.bmi()) #25.0

但是调用该方法给了我预期的值:

print(m_hum.bod_mass_idx()) #12.5
print(hum.bod_mass_idx()) #25.0
  1. 为什么该对象会以这种方式表现?
  2. 这种情况的解决方法是什么?

在我的例子中,父类帮助设置具有某些“基本”条件的模拟,而子类向模拟添加了某些怪癖。我觉得最好不要重用代码来编写新的模拟,并决定使用 OOP :)

附注我是面向对象编程的新手,并且仍在研究术语。

python oop inheritance overriding
1个回答
0
投票

bmi
Human.__init__ 中使用
MetaHuman.__init__
将值更改为 
fraction 之前的硬编码值 1.0 计算一次
。由于它的值取决于可能改变的值(身高、体重、
前因子),因此最好按需计算它,而不是将其存储为属性。

class Human: def __init__(self, height, weight): self.height = height self.weight = weight self.prefactor = 1.0 @property def bmi(self): return self.prefactor * self.weight/self.height**2 class MetaHuman(Human): def __init__(self, height, weight, fraction): super().__init__(height, weight) self.prefactor = fraction
    
© www.soinside.com 2019 - 2024. All rights reserved.