> This is neat. :) Could that maybe be extended to only assign selected > args to the instance and let others pass unchanged. So that, for instance: > > @autoassign("foo", "bar") > def __init__(self, foo, bar, baz): > super(baz)
I've seen some folks import inspect/functools, but from my testing, the __init__ method in question has a .func_code object that already has the varnames in it. However, as you suggest, a version below allows for named defaults, and letting others go un-defaulted. I'm not sure about naming conventions for class-style decorators--start with a cap, like a class should ("AutoAssign") or because it behaves like a function, use "auto_assign", or any of a number of other variants. Anyways... class auto_assign(object): def __init__(self, *varnames): self.args = set(varnames) def __call__(self, fn): autoassign = self def wrapper(self, *args, **kwargs): for argname, argvalue in zip( fn.func_code.co_varnames[1:], args): if argname in autoassign.args: setattr(self, argname, argvalue) for argname in autoassign.args: if argname in kwargs: setattr(self, argname, kwargs[argname]) fn(self, *args, **kwargs) return wrapper class Foo(object): @auto_assign('foo', 'baz', 'fred') def __init__(self, foo, bar, baz, *args, **kwargs): pass f = Foo('hello', 42, 3.14, fred='wilma', barney='betty') try: print f.foo except AttributeError: print "Could not print f.foo" try: print f.bar except AttributeError: print "Could not print f.bar" try: print f.baz except AttributeError: print "Could not print f.baz" try: print f.fred except AttributeError: print "Could not print f.fred" try: print f.barney except AttributeError: print "Could not print f.barney" -tkc -- http://mail.python.org/mailman/listinfo/python-list