Question
Is it possible to instantiate an object, set an attribute of that object equal to a class method but delay the calling of that method while enabling access to that attribute (obj.name) without having to call it as a method (obj.name())
Background
I have a class that instantiates an object. Part of that instantiation is setting an attribute equal to a database object, which requires a lookup. This lookup, when instantiating many objects (several hundred), can be slow.
I would like to somehow delay that lookup until that information is needed. However, I don’t want to have to call a method on the object to do that lookup, I would like to simply access the attribute (object.attribute)
Simple Example / What I’ve Tried So Far
class Article(object):
def __init__(self, id, author):
self.id = id
# Note the lack of () after lookup_author below
self.author = self.lookup_author
# Temporary holding place for author data
self.__author = author
def lookup_author(self):
# A lookup that would be nice to delay / run as needed
# Would be something like Author.objects.get(author=self.__author)
# but set to something simple for this example
return '<Author: John Doe>'
article1 = Article(1, 'John Doe')
# Returns the bound method
# E.g. <bound method Article.lookup_author of <__main__.Article object at 0x100498950>>
print article1.author
# Calls the method properly, however, you have to use the method calling
# notation of .state() versus .state which is more natural and expected
# for attributes
# Returns <Author: John Doe>
print article1.author()
Using properties, you can have
article1.authoractually callself.lookup_authorand return it.output:
code:
For some reason, if needed,
__authordoesn’t have to even exist until the getter is used. You can do that using exceptions.