14. Slots: Avoiding Dynamically Created Attributes
By Bernd Klein. Last modified: 24 Mar 2024.
Avoiding Dynamically Created Attributes
The attributes of objects are stored in a dictionary __dict__
. Like any other dictionary, a dictionary used for attribute storage doesn't have a fixed number of elements. In other words, you can add elements to dictionaries after they are defined, as we have seen in our chapter on dictionaries. This is the reason, why you can dynamically add attributes to objects of classes that we have created so far:
class A(object):
pass
a = A()
a.x = 66
a.y = "dynamically created attribute"
The dictionary containing the attributes of "a" can be accessed like this:
a.__dict__
OUTPUT:
{'x': 66, 'y': 'dynamically created attribute'}
You might have wondered that you can dynamically add attributes to the classes, we have defined so far, but that you can't do this with built-in classes like 'int', or 'list':
x = 42
x.a = "not possible to do it"
OUTPUT:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-3-8c5f7956a976> in <module> 1 x = 42 ----> 2 x.a = "not possible to do it" AttributeError: 'int' object has no attribute 'a'
lst = [34, 999, 1001]
lst.a = "forget it"
OUTPUT:
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-4-df06616479b6> in <module> 1 lst = [34, 999, 1001] ----> 2 lst.a = "forget it" AttributeError: 'list' object has no attribute 'a'
If we generated a class in which usually only a few instances are needed in a program, - such as the Function class, - the advantages outweigh the disadvantages. The additional storage space for the dictionary brings us significant advantages for the design of our software. However, as soon as a high number of instances of a class must be generated in a program, the cost-benefit ratio can quickly reverse. The additionally required storage space can adversely affect or even prevent the execution of the program.
Python's slots are a nice way to work around this space consumption problem. Instead of having a dynamic dict
dictionary that allows adding attributes to objects dynamically, slots provide a static structure which prohibits additions after the creation of an instance.
When we design a class, we can use slots to prevent the dynamic creation of attributes. To define slots, you have to define a list with the name __slots__
. The list has to contain all the attributes, you want to use. Anything not in this list cannot be used as an attribute. We demonstrate this in the following class, in which the __slots__
list contains only the name for an attribute val
:
class S(object):
__slots__ = ['val']
def __init__(self, v):
self.val = v
x = S(42)
print(x.val)
x.new = "not possible"
OUTPUT:
42 --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-5-58aeffbcf9f0> in <module> 10 print(x.val) 11 ---> 12 x.new = "not possible" AttributeError: 'S' object has no attribute 'new'
If we start this program, we can see, that it is not possible to create dynamically a new attribute. We fail to create an attribute "new".
We mentioned in the beginning that slots are preventing a waste of space with objects. Since Python 3.3 this advantage is not as impressive any more. With Python 3.3 Key-Sharing Dictionaries are used for the storage of objects. The attributes of the instances are capable of sharing part of their internal storage between each other, i.e. the part which stores the keys and their corresponding hashes. This helps reducing the memory consumption of programs, which create many instances of non-builtin types.
Live Python training
Enjoying this page? We offer live Python training courses covering the content of this site.
Upcoming online Courses
24 Feb 2025 to 28 Feb 2025
31 Mar 2025 to 04 Apr 2025
07 Apr 2025 to 11 Apr 2025
19 May 2025 to 23 May 2025
02 Jun 2025 to 06 Jun 2025
30 Jun 2025 to 04 Jul 2025
11 Aug 2025 to 15 Aug 2025
10 Mar 2025 to 14 Mar 2025
07 Apr 2025 to 11 Apr 2025
23 Jun 2025 to 27 Jun 2025
28 Jul 2025 to 01 Aug 2025
12 Mar 2025 to 14 Mar 2025
09 Apr 2025 to 11 Apr 2025
04 Jun 2025 to 06 Jun 2025
30 Jul 2025 to 01 Aug 2025
Machine Learning from Data Preparation to Deep Learning
10 Mar 2025 to 14 Mar 2025
07 Apr 2025 to 11 Apr 2025
02 Jun 2025 to 06 Jun 2025
28 Jul 2025 to 01 Aug 2025
To see all course offerings: Enrol here