开发者

Python paradigm for "derived fields"/"class attributes from calculations"

I have a class开发者_如何学Go that, let's say, computes a person's insurance risk, and a few other variables are computed during computation. I will need access to the risk and the other variables later.

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

Now in some other function I do:

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

Is this a legitimate structure for the sort of program I want? Just throw an exception of the computation hasn't been run, to prevent getting bogus values?


No, it is not a legitimate thing to raise a NotYetCalculatedError ever, in any program (unless the calculation would take hours of work).

get_other_var() should automatically calculate the risk

What you actually want to do is run all the calculations when you initialize the class, or if you can't do that, you'll want to do this:

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

Then you can access InsuranceRiskModel(bob).risk or InsuranceRiskModel(bob).other_var anytime and the calculations will be done transparently.

To answer your more general question, the "python paradigm for [class attributes represented by] stored calculations" is the class property abstraction, involving transparent user-defined getters and setters and deleters, as demonstrated above; more info here http://docs.python.org/library/functions.html#property


Why not:

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

?

It is not Python specific. If users of you class need other_var and it is mandatory that risk should be calculated before it, it is better just calculate it silently.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜