Ian Bicking: the old part of his blog

Re: Reducing boilerplate code in __init__

I took a crack at writing a simple "autoinit" decorator. It's not "complete" in that it doesn't do all the minor tasks like setting the wrapping functions name, doc string, etc. nor does it preserve the function signature of the wrapped function, but it does do everything else. One minor "issue" is that it will assign every keyword argument to the instance, not just declared ones:

from itertools import izip

def autoinit(f):
  # get arg names minus 'self'
  argnames = f.func_code.co_varnames[1:f.func_code.co_argcount]
  # get argument defaults
  argdefs = f.func_defaults
  # build defaults dictionary
  if argdefs:
      defdict = dict(izip(argnames[-len(argdefs):], argdefs))
  else:
      defdict = {}
  def newf(self, *args, **kwargs):
      selfdict  = self.__dict__
      # start with argument defaults
      selfdict.update(defdict)
      # add positional arguments
      selfdict.update(izip(argnames, args))
      # add keyword arguments
      selfdict.update(kwargs)
      # call the original function
      return f(self, *args, **kwargs)
  return newf
Comment on Reducing boilerplate code in __init__
by Shahms King