Python中“派生字段”/“从计算中获得的类属性”的范式

5 投票
2 回答
1049 浏览
提问于 2025-04-16 20:08

我有一个类,假设它用来计算一个人的保险风险,同时在计算过程中还会计算一些其他的变量。之后我需要用到风险和其他变量的值。

class InsuranceRiskModel:

    self.risk = None
    self.other_var = None
    ...

    def get_risk():
        # do a bunch of calculations, 
        # which in the meantime fills out a bunch of other vars
        self.other_var = 5
        self.risk = 6
        return self.risk

    def get_other_var():
        # risk hasn't been calculated
        if not self.risk:
            raise NotYetCalculatedError("Not yet calculated!")
        return self.other_var

现在在另一个函数里,我做了:

r = InsuranceRiskModel(person)
risk = r.get_risk()
other_var = r.get_other_var()

这样设计程序合理吗?如果计算没有执行,就抛出一个异常,以防得到错误的值?

2 个回答

1

为什么不这样做:

def get_other_var():
    # risk hasn't been calculated
    if not self.risk:
        self.risk = self.get_risk()
    return self.other_var

这并不是说只适用于Python。如果你这个类的用户需要other_var,而且在计算other_var之前必须先计算risk,那么最好就默默地先计算risk

6

不,抛出一个 NotYetCalculatedError 的做法在任何程序中都是不合理的(除非这个计算需要花费几个小时)。

get_other_var() 应该自动计算风险。

你实际上想要做的是在初始化这个类的时候就运行所有的计算,或者如果你不能这样做,你可以这样做:

class InsuranceRiskModel(object):
    def __init__(self, person):
        self.person = person
        self.calculated = False

    def calculateModel(self):
        if not self.calculated:
            self.risk = 6
            self.other_var = 5
            self.calculated = True

    @property
    def risk(self):
        self.calculateModel()
        return self.risk

    @property
    def other_var(self):
        self.calculateModel()
        return self.other_var

这样你就可以随时访问 InsuranceRiskModel(bob).riskInsuranceRiskModel(bob).other_var,而计算会自动完成。

至于你更一般的问题,"python 中用于[类属性表示的]存储计算的范式"就是类属性抽象,这涉及到透明的用户自定义获取器、设置器和删除器,正如上面所示;更多信息可以查看这里 http://docs.python.org/library/functions.html#property

撰写回答