Sometimes I like to write getter attributes for an object such that the first time they are called, the heavy lifting is done once, and that value is saved and returned on future calls. In objective-c I would use an ivar or a static variable to hold this value. Something like:
- (id)foo
{
if ( _foo == nil )
{
_foo = // hard work to figure out foo
}
return _foo
}
Does this same pattern hold up well in Python, or is there a more accepted way of doing this? I have basically the same thing so far. What I don't like about my solution is that my object gets cluttered up with values and getters for those values:
def foo(self):
if not hasattr(self, "mFoo":
self.mFoo = # heavy lifting to compute foo
return self.mFoo
Use a lazy property instead. Getters are so 1990's.
Instead of doing an explicit "hasattr" test every time, let the Python runtime do that for you. Define __getattr__
in your class, which is only called when an undefined attribute is referenced.
class Sth(object):
@property
def a(self):
print "property a"
return self._a
def _a_compute(self):
# put expensive computation code here
print "_a_compute"
return 1000
def __getattr__(self, attr):
print "__getattr__"
if attr == '_a':
self._a = self._a_compute()
return self._a
ss = Sth()
print "first time"
print ss.a
print
print "second time"
print ss.a
Prints the following:
first time
property a
__getattr__
_a_compute
1000
second time
property a
1000
You could leave out the property and have __getattr__
test for 'a' directly, but then you wouldn't have the visibility to 'a' as an attribute in dir
for things like introspection or IDE autocomplete.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With