Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Python - Use of slots
Python's __slots__ is a class attribute that restricts which attributes can be assigned to instances, providing memory optimization and faster attribute access. By defining slots, Python avoids creating a __dict__ for each instance, significantly reducing memory usage.
Syntax
class MyClass:
__slots__ = ('attr1', 'attr2', 'attr3')
The __slots__ attribute accepts a tuple, list, or any iterable containing the names of allowed attributes. Once defined, instances can only have these specific attributes.
Basic Usage of Slots
Here's a simple example demonstrating how slots work ?
class Person:
__slots__ = ('name', 'age')
def __init__(self, name, age):
self.name = name
self.age = age
person1 = Person('Alice', 30)
print(person1.name)
print(person1.age)
person2 = Person('Bob', 25)
print(person2.name)
print(person2.age)
Alice 30 Bob 25
In this example, the Person class uses slots to restrict instances to only name and age attributes. This prevents the creation of __dict__ for each instance, saving memory.
Slots with Optional Attributes
You can initialize some slot attributes to None and assign them later ?
class Employee:
__slots__ = ('name', 'age', 'salary', 'address', 'email')
def __init__(self, name, age):
self.name = name
self.age = age
self.salary = None
self.address = None
self.email = None
e1 = Employee('Alice', 30)
e1.salary = 50000
e1.address = '123 Main St'
e1.email = 'alice@example.com'
print(f"Employee: {e1.name}, Age: {e1.age}")
print(f"Salary: ${e1.salary}, Email: {e1.email}")
Employee: Alice, Age: 30 Salary: $50000, Email: alice@example.com
Memory Comparison
Let's compare memory usage between regular classes and classes with slots ?
import sys
class RegularClass:
def __init__(self, x, y):
self.x = x
self.y = y
class SlottedClass:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
# Create instances
regular = RegularClass(1, 2)
slotted = SlottedClass(1, 2)
# Compare memory usage
print(f"Regular class size: {sys.getsizeof(regular.__dict__)} bytes")
print(f"Slotted class size: {sys.getsizeof(slotted)} bytes")
Regular class size: 296 bytes Slotted class size: 48 bytes
Restrictions of Slots
Attempting to assign an attribute not defined in slots raises an AttributeError ?
class RestrictedClass:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
obj = RestrictedClass(1, 2)
print(f"x: {obj.x}, y: {obj.y}")
try:
obj.z = 3 # This will raise an error
except AttributeError as e:
print(f"Error: {e}")
x: 1, y: 2 Error: 'RestrictedClass' object has no attribute 'z'
When to Use Slots
| Use Slots When | Avoid Slots When |
|---|---|
| Creating many instances | Need dynamic attributes |
| Memory is a concern | Using multiple inheritance |
| Fixed set of attributes | Need __dict__ access |
| Performance is critical | Prototyping/flexibility needed |
Conclusion
Python's __slots__ provides significant memory savings and faster attribute access by restricting instance attributes. Use slots when creating many instances with fixed attributes, but avoid them when you need dynamic attribute assignment or multiple inheritance.
