Skip to content

Instantly share code, notes, and snippets.

@lxyu
Last active August 29, 2015 14:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lxyu/62ed36ab15e20e3aa23d to your computer and use it in GitHub Desktop.
Save lxyu/62ed36ab15e20e3aa23d to your computer and use it in GitHub Desktop.
Dynamic generate function with ordered default kwargs in python
import types
def init_generator(spec):
"""Generate `__init__` function based on spec
"""
varnames, defaults = zip(*spec)
varnames = ('self', ) + varnames
def init(self):
kwargs = locals()
kwargs.pop('self')
self.__dict__.update(kwargs)
code = init.__code__
new_code = types.CodeType(len(spec) + 1,
0,
len(spec) + 2,
code.co_stacksize,
code.co_flags,
code.co_code,
code.co_consts,
code.co_names,
varnames,
code.co_filename,
"__init__",
code.co_firstlineno,
code.co_lnotab,
code.co_freevars,
code.co_cellvars)
return types.FunctionType(new_code,
{"__builtins__": __builtins__},
argdefs=defaults)
class A(object):
pass
spec = [('a', 1), ('b', 'foo'), ('c', None)]
A.__init__ = init_generator(spec)
a = A(2, c='wow!')
# {'a': 2, 'b': 'foo', 'c': 'wow!'}
print(a.__dict__)
import inspect
# ArgSpec(args=['self', 'a', 'b', 'c'], varargs=None, keywords=None, defaults=(1, 'foo', None))
print(inspect.getargspec(A.__init__))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment