Default attribute values pattern

George Sakkis george.sakkis at gmail.com
Mon Jan 21 14:30:07 EST 2008


On Jan 19, 6:02 pm, "David Tweet" <davidtw... at gmail.com> wrote:
> 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)


The problem with this (apart from being somewhat more verbose and less
explicit) is that you have to set existing attributes (like x and y)
*after* the call to super __init__ while new attributes (like z, a and
b) *before* the call. Mixing it up will either raise a runtime error
for passing an unknown argument to the parent, or (worse) set the
parent's default instead of the child's. So for the common attribute
setting case it involves more error-prone boilerplate code.

George



More information about the Python-list mailing list