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. > > ie. > > class BaseClass: > @classmethod > 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 > used).
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): ... @LazyClassAttribute ... def dataset(cls): ... print 'calculating dataset' ... return 'dataset(%s)' % cls.params ... >>> class Child1(Base): ... params = 'foo' ... >>> class Child2(Base): ... params = 'bar' ... >>> Child1.dataset calculating dataset 'dataset(foo)' >>> Child1.dataset 'dataset(foo)' >>> Child2.dataset calculating dataset 'dataset(bar)' >>> Child2.dataset 'dataset(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 accessed. STeVe -- http://mail.python.org/mailman/listinfo/python-list