Here is another version implemented as a decorator.
Actually I’d also like not to use inspect, but didn’t find any nice way to get the kwargs default values without it, any suggestion?
import inspect
def autoinit(decorated_init):
def _wrap(*args, **kwargs):
obj, nargs= args[0], args[1:]
names = decorated_init.func_code.co_varnames[1:len(nargs)+1]
nargs = {k: nargs[names.index(k)] for k in names}
kwa_keys = decorated_init.func_code.co_varnames[len(nargs)+1:]
kwa_defaults = inspect.getargspec(decorated_init).defaults
for k in kwa_keys:
nargs[k] = kwargs[k] if (k in kwargs) else kwa_defaults[kwa_keys.index(k)]
for k, v in nargs.iteritems():
setattr(obj, k, v)
return decorated_init(*args, **kwargs)
return _wrap
if __name__ == '__main__':
class Foo():
@autoinit
def __init__(self, a, b, x=0, y=0):
self.p = 'Hello, I am set inside the __init__'
self.s = self.a + self.b + self.x + self.y
f = Foo(1, 2, x=120, y=5)
for param in 'abxyps':
print param, '=>', getattr(f, param)
f = Foo(31, 33, x=64)
for param in 'abxyps':
print param, '=>', getattr(f, param)
f = Foo(7, 121)
for param in 'abxyps':
print param, '=>', getattr(f, param)