Skip to content

Instantly share code, notes, and snippets.

@metatoaster
Last active August 29, 2015 13:58
Show Gist options
  • Select an option

  • Save metatoaster/9947308 to your computer and use it in GitHub Desktop.

Select an option

Save metatoaster/9947308 to your computer and use it in GitHub Desktop.
import inspect
import functools
def arg2attr(clsins_init):
@functools.wraps(clsins_init)
def initattrs(self, *a, **kw):
# build default dict from default args, in reverse order due to
# the definition syntax is designed.
argspec = inspect.getargspec(clsins_init)
default_kw = {k: v for k, v in zip(
reversed(argspec.args),
reversed(argspec.defaults),
)}
# update the default with args, with the explicit self stripped.
default_kw.update({k: v for k,v in
zip(argspec.args[1:], a)})
# finally update with keyword arguments.
default_kw.update(kw)
for k, v in default_kw.iteritems():
setattr(self, k, v)
clsins_init(self, *a, **kw)
return initattrs
class Foo(object):
@arg2attr
def __init__(self, keyword, target='foo', counter=42):
print self.keyword
print self.target
print self.counter
foo1 = Foo('asdf')
assert foo1.keyword == 'asdf'
assert foo1.target == 'foo'
assert foo1.counter == 42
foo2 = Foo('hello', counter=0)
assert foo2.keyword == 'hello'
assert foo2.target == 'foo'
assert foo2.counter == 0
foo3 = Foo(counter=123, keyword='abcd')
assert foo3.keyword == 'abcd'
assert foo3.target == 'foo'
assert foo3.counter == 123
foo4 = Foo('a', 'b', 'c')
assert foo4.keyword == 'a'
assert foo4.target == 'b'
assert foo4.counter == 'c'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment