one-time initialization of class members
James Turk
james.p.turk at gmail.com
Wed Jun 13 21:43:04 EDT 2007
On Jun 13, 9:03 pm, Steven D'Aprano
<s... at REMOVE.THIS.cybersource.com.au> wrote:
> On Wed, 13 Jun 2007 23:55:02 +0000, James Turk wrote:
> > On Jun 13, 6:54 pm, Steven Bethard <steven.beth... at gmail.com> wrote:
> >> James Turk wrote:
> >> > Hi,
>
> >> > I have a situation where I have some class members that should only be
> >> > done once. Essentially my problem looks like this:
>
> >> > class Base(object):
> >> > dataset = None
>
> >> > def __init__(self, param):
> >> > if type(self).dataset is None:
> >> > # code to load dataset based on param, expensive
>
> >> > class ChildClass1(Base):
> >> > def __init__(self):
> >> > Base.__init__(self, data_params)
>
> >> > class AnotherChildClass(Base):
> >> > def __init__(self):
> >> > Base.__init__(self, other_data_params)
>
> >> > This seems to work, initialization is only done at the first creation
> >> > of either class. I was just wondering if this is the 'pythonic' way
> >> > to do this as my solution does feel a bit hackish.
>
> >> What should happen with code like::
>
> >> ChildClass1('foo')
> >> ChildClass1('bar')
>
> >> The 'param' is different, but 'dataset' should only get set the first time?
>
> >> STeVe
>
> > ChildClass doesn't take the parameter in it's constructor, it supplies
> > it for the BaseClass. Every ChildClass of the same type should use
> > the same dataset.
>
> Then each type of ChildClass should be a sub-class, and provide it's own
> dataset:
>
> class BaseClass:
> dataset = None
> # blah blah blah...
>
> class ChildClass1(BaseClass):
> dataset = SomethingUseful
>
> class ChildClass2(BaseClass):
> dataset = SomethingElse
>
> --
> Steven.
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). I believe I have two options:
1) put each ChildClass in a separate file
2) in each ChildClass constructor put a check if the dataset has been
loaded yet, so that the first time an instance is created it can call
the BaseClass.loadData
for now I have chosen the second option, which is to change the child
classes to resemble
class ChildClass(BaseClass):
dataset = None
def __init__(self):
if BaseClass.dataset is None:
self(type).dataset = BaseClass.loadData(params)
I am still doing the self(type) access, but I like it more now that
I've taken it out of the BaseClass constructor.
More information about the Python-list
mailing list