Python allows faster creation of classes by implementing __slots__, which would feel like giving your class a list of rules it can follow, and things it cannot do. Assume __slots__ like a backpack with a limited amount of space. When you only pack the things you need, your bag is light and organised. Python classes, in this case, act in the same manner. Without the implementation of __slots__, they carry around extra space that is not always useful. In this blog, you will explore how to optimize memory usage by using slots, leading to cleaner, more efficient code.
Table of Contents:
What are __slots__ in Python?
In Python, __slots__ is a special feature you can use inside a class to limit what attributes (variables) that class can have. Normally, Python stores all your object’s attributes in a dictionary. This adds flexibility but also ends up taking more memory than usual. When you use __slots__, you tell Python that you are using these specific attributes. What Python does in return is that it doesn’t create the attribute dictionary, which uses less memory for your program and gives slightly faster access to attributes, especially when you are working with a large number of objects.
Implementing __slots__ to your code gives structure and predictability to your class objects. It proves beneficial when you’re optimizing your code.
Why Use __slots__ Instead of Using Regular Attributes in Python?
Using __slots__ saves space because Python skips making the usual __dict__ for each object. Also, accessing attributes is slightly faster with __slots__, since Python already knows exactly what attributes to expect. This keeps your code efficient and prevents bugs from adding other unintentional attributes.
How Python Stores Object Attributes?
Normally, Python stores each object’s attributes in something called a __dict__. This is a hidden dictionary that keeps track of all the variables you attach to an object.
Example:
Output:
Explanation: Here, you can see that Python keeps a dictionary for the object’s attributes. This uses memory to manage flexibility, but you can still add or remove attributes whenever you feel like it.
Boost your tech career with Python – Sign up now!
Practical projects, job-ready skills, and expert guidance.
Using __slots__ in a Python Class
Let’s take the same class example and explore how using __slots__
modifies its behavior. This will provide a clear comparison of the impact on memory usage and attribute management.
Example:
Output:
Explanation: Here, you can see Python stores the attribute that is “name” in this case, in a fixed way instead of using a dictionary. This results in efficient memory usage and speeds up access to the ‘name’ attribute.
When you define a class with slots, you restrict the attributes that can be assigned to instances of that class. If you attempt to add an attribute that is not listed in slots, Python will raise an AttributeError, because it doesn’t have a dict to store arbitrary attributes.
Example:
Output:
Explanation: Here, ‘age‘ was not listed in the __slots__, and Python raises an AttributeError when you try to add attributes not listed in __slots__, unless __dict__ is included explicitly in the slot list. This helps prevent mistakes and ensures that the object’s memory footprint remains small.
Combining Inheritance with __slots__ in Python
When you begin to combine __slots__ with inheritance, it becomes a little complex. If a parent class uses __slots__, the child class would not inherit those slots unless you explicitly define them. Remember that when using __slots__ in a child class, you must define __slots__ explicitly in that class. Also, if you don’t define an __init__ method, initialization logic might break, and the class may not function as expected. Also remember, if you skip declaring __slots__ in the child class, it will fallback to using a __dict__, negating the memory benefits. Always define __slots__ in both parent and child classes to preserve performance improvements.
Example:
Output:
Explanation: Here, the ‘name’ from the parent class and ‘grade’ from the child class are both usable. All you have to do is define __slots__ in both the Python classes for it to work. Just remember that you are setting attributes without defining an __init__ method in the child class, which means it could break if initialization logic is needed, so the performs only in this case.
When You Should and Shouldn’t Use __slots__ in Python
Using __slots__ can make your classes more efficient, but it’s not always the right choice.
Let’s now see when it’s a good idea to use it and when it’s better to avoid it.
When to Use __slots__ in Python:
- Creating many objects: Useful when making many class objects to save memory.
- Saving memory: Removes the default space used for storing object data.
- Faster attribute access: Getting or changing values becomes a little faster.
- Avoiding mistakes: Helps stop adding extra attributes by accident.
When Not to Use __slots__ in Python:
- Need to add attributes later: Not good if you need to add new data to objects.
- Using multiple base classes: Doesn’t work well with more than one parent class.
- Need weak references: Slotted classes do not support weak references by default. To enable them, include ‘__weakref__’ in the __slots__ definition.
You can utilise a tool like sys.getsizeof() or memory profilers so that you can measure object memory usage.
Example:
Output:
Explanation: Here, the comparison reflects that Slotted objects use less memory than Regular ones. Now, by preventing the creation of __dict__, __slots__ help Python to allocate a leaner memory footprint per object.
Using __slots__ with @property in Python
You can try using @property decorators while implementing __slots__, this will allow you to create getter and setter methods while also keeping the memory benefits. Remember that the attributes used in the property methods must be included in __slots__.
Example:
Output:
Explanation: Here, the @property and @name.setter methods work perfectly with slotted classes. The only requirement is that the internal attribute (like _name) must be included in the __slots__ list.
Preventing Attribute Deletion with __slots__
When you define attributes using __slots__, Python creates descriptors that can be further customised. For example, try blocking the deletion of attributes.
Example:
Output:
Explanation: Here, __slots__ attributes can be deleted using del, but once deleted, you can’t access them unless reassigned. To block deletion, you’d need to implement custom descriptors. The example here shows that once an attribute defined in __slots__ is deleted, it cannot be accessed again unless reassigned.
Get 100% Hike!
Master Most in Demand Skills Now!
With vs. Without __slots__ in Python
Feature |
With __slots__ |
Without __slots__ |
Memory usage |
Lower, no __dict__ is created |
Higher memory usage as it stores all attributes in __dict__ |
Attribute flexibility |
Can only use listed attributes |
Can add any new attribute. |
Attribute access speed |
Slightly faster due to fixed slots |
It is slightly lower due to dictionary lookup |
Inheritance complexity |
More complex, must define slots in child classes |
Simple |
Debugging and flexibility |
It is better for performance-focused applications |
Easier for dynamic and flexible objects |
Common Mistakes to Avoid
Keep a check for these mistakes that you might come across while coding:
- Forgetting to list all used attributes inside __slots__.
- Using __slots__ with multiple inheritance without control.
- Assigning attributes that aren’t defined.
- Assuming __slots__ will always bring massive speed boosting, it’s mainly for memory savings.
Real-World Examples of Using __slots__ in Python
The below segment contains three examples to show you the implementation of __slots__ in real-world programming.
1. A Game Character: Let us take two instance attributes as ‘name’ and ‘healthbar’ for a game character, and then implement __slots__.
Example:
Output:
Explanation: Here, both attributes ‘label’ and ‘healthbar’ are defined in __slots__, so the Python language generates a lightweight structure for the object while the attributes are stored directly in memory without a __dict__, giving us better performance.
2. Sensors in IoT: We take two variables or instance attributes as ‘id’ and ‘value’ for sensors, and then we use __slots__
Example:
Output:
Explanation: Here, only two attributes are being held for each sensor object, being stored efficiently using __slots__. This design allows thousands of such objects to exist simultaneously without consuming excess memory.
3. Storing records of temperature readings: Let us build a sample data model for storing temperature readings.
Example:
Output:
Explanation: Here, this example shows how __slots__ work great even with classes that include methods. It is perfect for lightweight data models where performance and memory usage are priorities.
Best Practices for Using __slots__ in Python
- Try using it if your first concern is memory usage: This will help you save memory in object creation at a large scale.
- It is better if you list all attributes that the class will refer to/use: Not having any can give an AttributeError on assignment.
- Avoid using slots if you need to add dynamic attributes: Unlisted attributes are prevented from being created by __slots__.
- Both parent and child classes should have __slots__ defined in them: Inheritance does not automatically carry over slots.
- Keep a habit of testing functionality and memory before using it and after using it: Make sure that __slots__ give actual benefits in your case.
Learn Python for Free – Start Coding Today!
Dive into Python with our beginner-friendly course
Conclusion
Now, you have an understanding of __slots__, how they function, and when to use them. It keeps your code faster and lighter, especially when you’re creating loads of objects. We also saw how Python normally keeps track of object attributes using a dictionary, and how __slots__ replaces that with a more efficient way to store only specific variables. We explored how it affects inheritance, flexibility, and memory usage. Most importantly, we tested code examples to check the reliability of the __slots__ method.
To take your skills to the next level, enroll in our Python training course and gain hands-on experience. Also, prepare for job interviews using our Python interview questions, designed by industry experts.
Slots in Python – FAQs
Q1. Does implementing __slots__ make my program faster?
Yes, __slots__ can make your program faster by saving memory and speeding up attribute access.
Q2. Can I still try using @property with __slots__?
Yes, you can use @property with __slots__, but the attributes used in the property methods must be listed in __slots__.
Q3. Can I assign default values to attributes in a __slots__ class?
No, you cannot assign default values to attributes in a __slots__ class directly; you must initialize them in the __init__ method.
Q4. What happens if I do not add an attribute to __slots__?
If you don’t add an attribute to __slots__, an AttributeError will be raised when you try to access or assign a value to it.
Q5. Can I input methods in a class that uses __slots__?
Yes, you can define methods in a class that uses __slots__ just like in any regular class.