On Jan 28, 4:47 am, "Gabriel Genellina" <[EMAIL PROTECTED]> wrote: > En Sun, 27 Jan 2008 23:51:28 -0200, Arnaud Delobelle > <[EMAIL PROTECTED]> escribió: > > > Nice! I've got a slight variation without magic argument names: > > > class Test(object): > > @autoassign('foo', 'bar') > > def __init__(self, baz): > > print 'baz =', baz [...] > I would like a signature-preserving version. The help system, pydoc, the > inspect module, and likely any other introspection tool see those > decorated methods with a different signature than the original one. > Even if one writes a signature-preserving decorator (maybe along the lines > of this article by M. Simionato [1]), names like "self_foo", "self_bar" > are ugly. Furthermore, argument names are part of the public interfase, > but here they're tied to the implementation: what if later I want to keep > a reference to baz? I must change the argument name to self_baz, breaking > all users of the code.
Sligthly improved (not for performance! but signature-preserving and looks for default values) from functools import wraps from inspect import getargspec from itertools import izip, chain def autoassign(*names): def decorator(f): fargnames, _, _, fdefaults = getargspec(f) defaults = [(n,v) for (n,v) in izip(reversed(fargnames), reversed(fdefaults)) if n in names] @wraps(f) def decorated(self, *args, **kwargs): self.__dict__.update(defaults) for name, arg in chain(izip(fargnames, args), kwargs.iteritems()): if name in names: setattr(self, name, arg) return f(self, *args, **kwargs) return decorated return decorator class Test(object): @autoassign('foo', 'bar') def __init__(self, foo, bar=3, baz=6): print 'baz =', baz t = Test(1, 2, 6) u = Test(foo=8) print t.foo # 1 print t.bar # 2 print u.foo # 8 print u.bar # 3 (default) -- Arnaud print t.baz # AttributeError -- http://mail.python.org/mailman/listinfo/python-list