Every once in a while, I get fed up of having to do lots of
self.foo = foo in Python
__init__ methods, and wonder if it couldn't be done automatically. I came up with the following function to do just that, but I doubt I'll ever use it myself, because it goes against the *explicit is better than implicit* philosophy of Python.
#!/usr/bin/env python
import inspect
def init_from_args():
frame = inspect.stack()[1][0]
code = frame.f_code
var_names = code.co_varnames # __init__'s parameters and locals
init_locals = frame.f_locals # __init__'s dict of locals
num_args = code.co_argcount # Number of arguments
arg_names = var_names[1:num_args] # Positional argument names
# If there's a **kwargs parameter, get the name of it
kw_name = None
if code.co_flags | 12:
kw_name = var_names[num_args + 1]
elif code.co_flags | 8:
kw_name = var_names[num_args]
# Copy the positional arguments
for name in arg_names:
setattr(init_locals[var_names[0]], name, init_locals[name])
# If there was a **kwargs parameter, copy the keywork arguments.
if kw_name:
for name, value in init_locals[kw_name].items():
setattr(init_locals[var_names[0]], name, value)
class Foo:
def __init__(self, a, b, *args, **kwargs):
init_from_args()
bar = 123
baz = "hello"
quux = "foo"
if __name__ == "__main__":
foo = Foo(1, 2, 3, something="something else")
print foo.__dict__
No comments:
Post a Comment