one-time initialization of class members
steven.bethard at gmail.com
Thu Jun 14 05:42:36 CEST 2007
James Turk wrote:
> It actually occured to me that I could use a @classmethod to do the
> loading and take that out of the BaseClass constructor. What I have
> makes more sense and eliminates the unecessary constructors.
> class BaseClass:
> def loadData(params):
> #expensive load here
> class ChildClass1(BaseClass):
> dataset = BaseClass.loadData(params)
> This is pretty much along the lines of what you suggested, thank you
> for the hint in the right direction.
> I realized that this still doesn't meet my needs exactly as I only
> want the expensive dataset to be loaded if/when a class is actually
> used (there are potentially many of these and only a few will be
Seems like you want a lazy class attribute. How about something like::
>>> class LazyClassAttribute(object):
... def __init__(self, func):
... self.func = func
... def __get__(self, obj, cls=None):
... value = self.func(cls)
... setattr(cls, self.func.__name__, value)
... return value
>>> class Base(object):
... def dataset(cls):
... print 'calculating dataset'
... return 'dataset(%s)' % cls.params
>>> class Child1(Base):
... params = 'foo'
>>> class Child2(Base):
... params = 'bar'
The idea is basically similar to the @classmethod approach except that
instead of @classmethod, we use a custom descriptor that calls the
method the first time it's accessed and then stores that value
afterwards. This means that instead of explicitly calling the
@classmethod, the method will be called whenever the attribute is first
More information about the Python-list