Esto puede ser un poco tarde, pero hice una solución usando Python Meta-Classes (versión de decorador a continuación también)
Cuando __init__
se llama durante el tiempo de ejecución, toma cada uno de los argumentos y su valor y los asigna como variables de instancia a su clase. De esta manera, puede crear una clase de estructura sin tener que asignar cada valor manualmente.
Mi ejemplo no tiene verificación de errores, por lo que es más fácil de seguir.
class MyStruct(type):
def __call__(cls, *args, **kwargs):
names = cls.__init__.func_code.co_varnames[1:]
self = type.__call__(cls, *args, **kwargs)
for name, value in zip(names, args):
setattr(self , name, value)
for name, value in kwargs.iteritems():
setattr(self , name, value)
return self
Aquí está en acción.
>>> class MyClass(object):
__metaclass__ = MyStruct
def __init__(self, a, b, c):
pass
>>> my_instance = MyClass(1, 2, 3)
>>> my_instance.a
1
>>>
Lo publiqué en reddit y / u / matchu publicó una versión de decorador que es más limpia. Te animo a que lo uses a menos que quieras expandir la versión de la metaclase.
>>> def init_all_args(fn):
@wraps(fn)
def wrapped_init(self, *args, **kwargs):
names = fn.func_code.co_varnames[1:]
for name, value in zip(names, args):
setattr(self, name, value)
for name, value in kwargs.iteritems():
setattr(self, name, value)
return wrapped_init
>>> class Test(object):
@init_all_args
def __init__(self, a, b):
pass
>>> a = Test(1, 2)
>>> a.a
1
>>>