As a Python programmer, I frequently declare classes similar to
class Foo:
def __init__(self, attr1, attr2, attr3, attr4, attr5, attr6, attr7, attr8, attr9):
self.attr1 = attr1
self.attr2 = attr2
...
self.attr9 = attr9
# init your class
The problem is that I do that over and over, and it feels very inefficient. In C++ the way to do this would be
class Foo {
public:
Foo(int, int, int, int, int);
private:
int attr1, attr2, attr3, attr4, attr5;
};
Foo::Foo(int attr1, int attr2, int attr3, int attr4, int attr5) :
attr1(attr1), attr2(attr2), attr3(attr3), attr4(attr4), attr5(attr5) {
// init your class
}
Which I feel like it's slightly more efficient. My question is: is there a standard way to avoid having to attribute the arguments to the class for every argument? I can think of ways to program it, for example
def attribute_setter(*arg_names):
def wrapper(func):
def setter_init(self, *args, **kwargs):
for i, name in enumerate(arg_names):
if i < len(args):
setattr(self, name, args[i])
elif name in kwargs:
setattr(self, name, kwargs[name])
func(self, *args, **kwargs)
return setter_init
return wrapper
class Foo:
@attribute_setter('attr1', 'attr2', 'attr3', 'attr4', 'attr5', 'attr6', 'attr7', 'attr8', 'attr9')
def __init__(self, *args, **kwargs):
# init your class
pass
Which yields
>>> foo = Foo(1, 2, 3, 4, 5, attr6=6, attr7=7, attr8=8, attr9=9)
>>> foo.attr1
1
>>> foo.attr9
9
With a lot more error handling, this decorator might become safe to use, but my concern is the readability of the code and making sure I'm not violating any good practice principle.
dataclass
ornamedtuple
– Malindamalinde