Isso pode ser um pouco tarde, mas eu fiz uma solução usando Python Meta-Classes (versão decoradora abaixo também).
Quando __init__
é chamado durante o tempo de execução, ele pega cada um dos argumentos e seus valores e os atribui como variáveis de instância à sua classe. Dessa forma, você pode criar uma classe do tipo struct sem precisar atribuir todos os valores manualmente.
Meu exemplo não possui verificação de erro, portanto é mais fácil segui-lo.
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
Aqui está em ação.
>>> class MyClass(object):
__metaclass__ = MyStruct
def __init__(self, a, b, c):
pass
>>> my_instance = MyClass(1, 2, 3)
>>> my_instance.a
1
>>>
Eu postou no reddit e / u / Matchu postou uma versão decorador que é mais limpo. Aconselho você a usá-lo, a menos que queira expandir a versão da metaclasse.
>>> 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
>>>