I've been reading about how make Python classes less dynamic, specifically by not allowing users to dynamically create new attributes. I've read that overloadding __setattr__
is a good way to do this , and __slots__
is not the way to go. One post on this last thread actually suggests that __slots__
can break pickling. (Can anyone confirm this?)
However, I was just reading the whatsnew for Python 2.2, and the attribute access section actually suggests using __slots__
for the very purpose of constraining attribute creation, not just for optimization like others have suggested. In terms of Python history, does anyone know what the original intention of __slots__
was? Is constraining variable creation a feature or a bug to be abused? How have people seen __slots__
used in practice? Have many people seen __setattr__
overloaded to restrict attribute creation? Which one is best? If you are more familiar with one method or the other, feel free to post the pros and cons of the method you know. Also, if you have a different way of solving the problem, please share! (And please try not to just repeat the downsides of __slots__
that have been expressed in other threads.)
EDIT: I was hoping to avoid discussion of "why?", but the first answer indicates that this is going to come up, so I'll state it here. In the project in question, we're using these classes to store "configuration information", allowing the user to set attributes on the objects with their (the users') parameters, and then pass the objects off to another part of the program. The objects do more than just store parameters, so a dictionary wouldn't work. We've already had users accidentally type an attribute name wrong, and end up creating a new attribute rather than setting one of the attributes that the program expects. This goes undetected, and so the user thinks they're setting the parameter but doesn't see the expected result. This is confusing for the user, and hard to spot. By constraining attribute creation, an exception will be thrown rather than pass by silently.
EDIT 2, re pickling: These objects will be something that we will want to store in the future, and pickling seems like a good way to do this. If __slots__
is clearly the best solution, we could probably find another way to store them, but pickling would definitely be of value, and should be kept in consideration.
EDIT 3: I should also mention that memory conservation isn't an issue. Very few of these objects will be created, so any memory saved will be negligible (like 10s of kilobytes on a 3-12 GB machine).
My suggestion for your use case is to use
__setattr__
and issue a warning when the attribute name is not recognized using Python's warnings module.