__slots__ is a special class variable in Python that restricts the attributes that can be assigned to an instance of a class.
__slots__ is an iterable(usually a tuple) that stores the names of the allowed attributes for a class. It specifies the list of attribute names that can be assigned to instances of the class.
If __slots__ is defined, an exception will be raised if an attribute that is not in the list is assigned to an instance.
In the above example, an AttributeError exception is raised, because we tried to assign attribute z to an instance when "z" is not present in the __slots__ list.
We also cannot add attributes to an instance dynamically.
Why is __slots__ important?
By default, class instances have a dictionary called __dict__ that stores all the attributes, and their associated values.
Using the dictionary, __dict__, allows for dynamic creation of attributes at runtime, which can be convenient but can also lead to potential memory inefficiency.
The __slots__ variable allows for more efficient memory usage as it limits the attributes that can be assigned to an instance to only those listed in __slots__ declaration.
Using __slots__ can offer considerable performance benefits because it eliminates the need for a dictionary to store attributes. When __slots__ is declared, the attributes are stored in a fixed-size array on the object itself. This makes accessing and setting attributes much faster as the interpreter does not have to perform dictionary lookups.
__slots__ is particularly useful when we know exactly what attributes class instances should have, and we don't want to assign arbitrary attributes dynamically at runtime.
__slots__ with inheritance
When a class defines __slots__, it only applies to instances of that class and does not automatically apply to its child classes. A child class does not inherit the parent class's __slots__.
By default, a child class will still use the __dict__ dictionary for storing the attribute, in addition to parents __slots__, unless it also defines its own __slots__.
A child class can also declare its own __slots__, without including those declared by its parent classes.