Hello, Seems to me that setattrs sort of assumes that you want to have all your initialization arguments set as attributes of the same name. I would think you'd sometimes want to be able to process the extra arguments inside of each __init__, assign them to attributes with different names, etc.
My approach would be to treat each __init__ as a wrapping function, grabbing the items it needs out of the keyword dictionary and then calling the next __init__. Curious to hear other approaches though: def Grab(argdict, key, default): """Like argdict.get(key, default), but also deletes key from argdict.""" if key in argdict: retval = argdict["key"] del(argdict[key]) else: retval = default return retval class Base(object): def __init__(self, x=0, y=None): print "in Base init" self.x = x self.y = y class Derived1(Base): def __init__(self, **kwargs): print "in Derived1 init" self.z = Grab(kwargs, "z", None) super(Derived1, self).__init__(**kwargs) class Derived2(Derived1): def __init__(self, **kwargs): print "in Derived2 init" self.a = Grab(kwargs, "a", 0) self.b = Grab(kwargs, "b", False) super(Derived2, self).__init__(**kwargs) print self.__dict__ newthing = Derived2(x=234, y="blah", a=55555) On Jan 19, 2008 10:14 AM, George Sakkis <[EMAIL PROTECTED]> wrote: > A situation that often comes up is having to initialize several > instance attributes that accept a default value. For a single class, > passing the default values in __init__ is fine: > > class Base(object): > def __init__(self, x=0, y=None): > self.x = x > self.y = y > > For inherited classes that need to override __init__ while keeping a > compatible interface though, the default values have to be repeated: > > class Derived(Base): > def __init__(self, x=0, y=None, z=''): > super(Derived,self).__init__(self,x,y) > self.z = '' > > For just two attributes and two classes that's maybe not too bad but > for many attributes and/or derived classes that may span multiple > modules, that doesn't seem to scale from a maintenance point of view, > especially if the defaults change over time. > > A pattern I've been using lately instead is store the defaults in > class attributes and let __init__ accept keyword arguments: > > class Base(object): > > x = 0 > y = None > > def __init__(self, **kwds): > setattrs(self, kwds) > > where setattrs is: > > def setattrs(self, attrvals, strict=True): > if strict: > # raise AttributeError if some attr doesn't exist already > for attr in attrvals.iterkeys(): > getattr(self,attr) > for attr,val in attrvals.iteritems(): > setattr(self, attr, val) > > This way, only the new and overriden default attributes have to > repeated in derived classes: > > class Derived(Base): > > x = 1 > z = '' > > def __init__(self, **kwds): > super(Derived,self).__init__(**kwds) > print 'In Derived.__init__' > > > Is this a good way of doing it ? Is there a better pattern ? > > George > -- > http://mail.python.org/mailman/listinfo/python-list > -- -David -- http://mail.python.org/mailman/listinfo/python-list