I see patterns like
def __init__(self, x, y, z):
...
self.x = x
self.y = y
self.z = z
...
quite frequently, often with a lot more parameters. Is there a good way to avoid this type of tedious repetitiveness? Should the class inherit from namedtuple
instead?
To expand on
gruszczy
s answer, I have used a pattern like:I like this method because it:
super().__init(...)
)X.__init__
Prior to Python 3.6, this gives no control over the order in which the attributes are set, which could be a problem if some attributes are properties with setters that access other attributes.
It could probably be improved upon a bit, but I'm the only user of my own code so I am not worried about any form of input sanitation. Perhaps an
AttributeError
would be more appropriate.A decorator solution that keeps the signature:
Disclaimer: It seems that several people are concerned about presenting this solution, so I will provide a very clear disclaimer. You should not use this solution. I only provide it as information, so you know that the language is capable of this. The rest of the answer is just showing language capabilities, not endorsing using them in this way.
There isn't really anything wrong with explicitly copying parameters into attributes. If you have too many parameters in the ctor, it is sometimes considered a code smell and maybe you should group these params into a fewer objects. Other times, it is necessary and there is nothing wrong with it. Anyway, doing it explicitly is the way to go.
However, since you are asking HOW it can be done (and not whether it should be done), then one solution is this:
My 0.02$. It is very close to Joran Beasley answer, but more elegant:
Additionally, Mike Müller's answer (the best one to my taste) can be reduced with this technique:
And the just call
auto_init(locals())
from your__init__
This is a solution without any additional imports.
Helper function
A small helper function makes it more convenient and re-usable:
Application
You need to call it with
locals()
:Test
Output:
Without changing
locals()
If you don't like to change
locals()
use this version:explicit is better than implicit ... so sure you could make it more concise:
The better question is should you?
... that said if you want a named tuple I would recommend using a namedtuple (remember tuples have certain conditions attached to them) ... perhaps you want an ordereddict or even just a dict ...