On Jan 28, 4:08 pm, "André" <[EMAIL PROTECTED]> wrote: [...] > If I may suggest, I would extend this so that autoassign's signature > would be as follows: > > autoassign(all=True, include_only=None, exclude=None) > > Either one of include_only or exclude could be a list of function to > which the automatic assignment would apply (or not). I was planning > to write this up and submit it to the cookbook later this evening, but > since the suggestion has been made, someone else can jump on it. ;-) > > André
I've modified my little decorator (see Test1, Test2, Test3 for usage). I'll post it later on the cookbook if there seems to be no bugs and noone raises valid point against it:) from functools import wraps from inspect import getargspec, isfunction from itertools import izip, ifilter, starmap def autoassign(*names, **kwargs): if kwargs: exclude, f = set(kwargs['exclude']), None sieve = lambda l:ifilter(lambda nv: nv[0] not in exclude, l) elif len(names) == 1 and isfunction(names[0]): f = names[0] sieve = lambda l:l else: names, f = set(names), None sieve = lambda l: ifilter(lambda nv: nv[0] in names, l) def decorator(f): fargnames, _, _, fdefaults = getargspec(f) # Remove self for fargnames and make sure fdefaults is a tuple fargnames, fdefaults = fargnames[1:], fdefaults or () defaults = list(sieve(izip(reversed(fargnames), reversed(fdefaults)))) @wraps(f) def decorated(self, *args, **kwargs): assigned = dict(sieve(izip(fargnames, args))) assigned.update(sieve(kwargs.iteritems())) # It would be nice to have a builtin to exhaust iterators: for _ in starmap(assigned.setdefault, defaults): pass self.__dict__.update(assigned) return f(self, *args, **kwargs) return decorated return f and decorator(f) or decorator class Test(object): @autoassign('foo', 'bar') def __init__(self, foo, bar=3, baz=6): print 'baz =', baz class Test2(object): @autoassign def __init__(self, foo, bar): pass class Test3(object): @autoassign(exclude=('foo', 'bar')) def __init__(self, foo, bar, baz=5, **kwargs): pass t = Test(1, 2, 5) u = Test(foo=8) v = Test2(10, 11) w = Test3(100, 101, foobar=102) print t.foo # 1 print t.bar # 2 print u.foo # 8 print u.bar # 3 (default) print v.foo, v.bar # 10 11 print w.baz, w.foobar # 5 102 for obj, attr in ('w', 'foo'), ('w', 'bar'), ('t', 'baz'): try: getattr(globals()[obj], attr) except AttributeError: print '%s.%s raises AttributeError' % (obj, attr) ==== output ==== baz = 5 baz = 6 1 2 8 3 10 11 5 102 w.foo raises AttributeError w.bar raises AttributeError t.baz raises AttributeError -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list