I have two classes, one of which is expensive to set up, but reusable, and the other of which will have many instances in my application, but can reuse an instance of the expensive class. This is easier to explain by example:
class SomeExpensiveToSetUpClass(object):
def __init__(self):
print("Expensive to set up class initialized")
self.whatever = "Hello"
def do_the_thing(self):
print(self.whatever)
class OftenUsedClass(object):
@staticmethod
@property
def expensive_property():
try:
return OftenUsedClass._expensive_property
except AttributeError:
OftenUsedClass._expensive_property = SomeExpensiveToSetUpClass()
return OftenUsedClass._expensive_property
# I know I could hide the static property in an instance property:
@property
def expensive_property2(self):
try:
return OftenUsedClass._expensive_property
except AttributeError:
OftenUsedClass._expensive_property = SomeExpensiveToSetUpClass()
return OftenUsedClass._expensive_property
#
# And then:
#
# ouc = OftenUsedClass()
# ouc.expensive_property2.do_the_thing()
# ouc.expensive_property2.do_the_thing()
# ouc.expensive_property2.do_the_thing()
#
# but that feels misleading
if __name__ == '__main__':
OftenUsedClass.expensive_property.do_the_thing()
OftenUsedClass.expensive_property.do_the_thing()
OftenUsedClass.expensive_property.do_the_thing()
As you can, see, I was hoping I would use @staticmethod
and @property
to essentially memoize the property on the first use of the property, but no dice--I'm getting an instance of property
back instead:
Traceback (most recent call last):
File "memo.py", line 39, in <module>
OftenUsedClass.expensive_property.do_the_thing()
AttributeError: 'property' object has no attribute 'do_the_thing'
I've found several patterns for memoization decorators, but none for static properties. Am I missing something? Or is there an alternate pattern I should be using?
Edit:
I oversimplified my question: I should have included that the name of the SomeExpensiveToSetUpClass
class implementation is supplied in a config file, and so I don't know its name at until the first time OftenUsedClass
is instantiated.