Typically all attributes are stored in the instance’s dictionary __dict__. This will add space overhead due to the hash table being sparse. We can save memory by storing all the attributes in a tuple-like data structure using __slots__ at the beginning of the class definition (see below):
import sys
class C:
def __init__(self, x, y):
self.x = x
self.y = y
class C_Slots:
__slots__ = ("x", "y")
def __init__(self, x, y):
self.x = x
self.y = y
print(sys.getsizeof(C)) #=> 904
print(sys.getsizeof(C_Slots)) #=> 1,072The main problems with __slots__:
- Can’t dynamically add attributes to the instance. We can work around this issue by adding
__dict__to__slots__but this negates the benefits of using__slots__. - Doesn’t support
__weakref__by default. We need to add__weakref__to__slots__to be able to use it. - All sublcasses have to declare
__slots__because attributes can’t be inheritted and will be ignored by the interpreter.
In conclusion, use __slots__ only if it is justified.