Reputation: 545
Very often my classes have a few attributes, and other object's properties depend on those. What is the best way to define and access those? A minimal example should explain what I'm asking.
Say that I have a class that defines a circle:
class Circle:
def __init__(self, r):
self.r = r
Now this circle is instantiated just based on the radius, but I may want to be able to access its diameter, these are the possibilities I see:
A) create a new attribute when instantiating
class Circle:
def __init__(self, r):
self.r = r
self.d = 2*r
B) define a function that returns the diameter
class Circle:
def __init__(self, r):
self.r = r
def d(self):
d = 2*r
return d
Solution A does not ensure consistency, if the user changes r, d is not automatically updated, and the mistake can be hard to track down. Solution B requires the user to call a function rather than accessing an attribute. And every time the attribute d has to be accessed, it has to be recalculated, and in general it might be time consuming.
Is there a solution C that ensures consistency and does not require the class user to recalculate the attribute every time it is accessed?
Upvotes: 2
Views: 387
Reputation: 1736
You could use a Python property here.
Here's a discussion of the built in property function in the docs:
http://docs.python.org/2/library/functions.html#property
In your case you could use it as follows:
def getdiameter(self):
return self.r * 2
def setdiameter(self, d):
self.r = d / 2
d = property(getdiameter, setdiameter)
You may want d to be readonly (it's purely a function of a radius). In this case, you can omit the setdiameter function from the property.
Update If d was very expensive to compute, then I would compute d when it was first read and invalidate d when r was computed.
def setr(self, r):
self.r = r
self.d = None
def getd(self):
if not self.d is None:
return self.d
self.d = self.r * 2 # Our expensive calculation
return self.d
Upvotes: 1