In Python, classes by default allow for dynamic creation of instance attributes, which provides flexibility but also comes with some overhead in terms of memory and performance. To make a class more memory-efficient and restrict the dynamic creation of instance attributes, Python provides the __slots__
mechanism.
Additionally, using __slots__
can make your class behave more like an immutable data structure, as it prevents adding new attributes that aren’t explicitly defined.
The __slots__
mechanism allows you to define a fixed set of attributes for your class, eliminating the need for a per-instance dictionary (__dict__
) to store attributes, which is the default behavior in Python objects.
__slots__
__slots__
, Python no longer needs to maintain an attribute dictionary (__dict__
) for each instance, which reduces the memory footprint, especially when dealing with many instances.__slots__
.__slots__
, you prevent adding new attributes to instances, making the class “semi-immutable” (though not truly immutable as existing attributes can still be changed).__slots__
can be created for instances of the class. If you try to assign an attribute that is not defined in __slots__
, Python will raise an AttributeError
.class Point:
__slots__ = ['x', 'y']
def __init__(self, x: int, y: int):
self.x = x
self.y = y
# Example usage
p1 = Point(1, 2)
print(p1.x, p1.y) # Outputs: 1 2
# Attempting to add a new attribute outside of __slots__
try:
p1.z = 3 # This will raise an AttributeError
except AttributeError as e:
print(e) # Outputs: 'Point' object has no attribute 'z'
__slots__
: In the Point
class, __slots__ = ['x', 'y']
is defined to restrict the class to only two attributes: x
and y
. This means each instance of Point
will only have space allocated for x
and y
—no dynamic attributes can be added beyond these.__init__
) initializes the attributes x
and y
using the provided values. You can access these attributes normally, like p1.x
and p1.y
.p1.z = 3
) that is not listed in __slots__
, Python raises an AttributeError
. This is because the Point
class does not allow any attributes beyond the ones defined in __slots__
.__slots__
__slots__
can reduce the memory footprint.__slots__
because it avoids dictionary lookups for instance attributes.__slots__
is a way to enforce that.__slots__
__slots__
cannot be added dynamically, which may limit flexibility in certain scenarios.__slots__
is inherited, the child class must define its own __slots__
or inherit from the parent properly. Otherwise, the benefits of using __slots__
can be negated.__dict__
or __weakref__
by default in classes with __slots__
, unless explicitly listed.