py3k feature proposal: field auto-assignment in constructors
Arnaud Delobelle
arnodel at googlemail.com
Mon Jan 28 07:09:48 EST 2008
On Jan 28, 4:47 am, "Gabriel Genellina" <gagsl-... at yahoo.com.ar>
wrote:
> En Sun, 27 Jan 2008 23:51:28 -0200, Arnaud Delobelle
> <arno... at googlemail.com> 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
More information about the Python-list
mailing list