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.
精彩评论