Understanding Slots in Python

Understanding Slots in Python

Creating objects for classes requires memory, and the stored attribute is in the form of a dictionary. It will take a lot of memory and indexing time if we need to allocate thousands of objects.

Slots or __slots__ provides a unique mechanism to reduce the size of objects and faster indexing. This article will discuss how the slots constant variable work in Python and how it is any better than using dictionaries.

Understanding Slots in Python

Slots is a concept of memory optimization on objects that would improve our Python code runtime. For example, when we create a custom object from a class, the attributes of the stored object in a dictionary are called __dict__.

In addition, it allows us to create new attributes after the creation of the object dynamically.

Without slots, our objects would look like the following snippet below.

Example Code:

class sample_class(object):
      def __init__(self, *args, **kwargs):
                self.key = 'foo'
                self.value = 'bar'

if __name__ == "__main__":
     sample_object = sample_class()
     print(sample_object.__dict__)

Output:

{'key': 'foo', 'value': 'bar'}

In Python, each object has a dynamic dictionary that supports adding attributes. We will have a dictionary instance for every instance object, taking up extra space and wasting a lot of RAM.

When creating an object in Python, there is no default functionality to allocate a set amount of memory for storing all its characteristics.

Utilizing __slots__, which allot space for a set number of attributes, reduces space wastage and speeds up the program.

Example Code:

class sample_class(object):
      __slots__ = ['key','value']

      def __init__(self, *args, **kwargs):
                self.key = 'foo'
                self.value = 'bar'

if __name__ == "__main__":
     sample_object = sample_class()
     print(sample_object.__slots__)

Output:

['key','value']

Notice that when calling the __slots__ variable, we only access the keys to map each value in a dictionary. Although Python’s dictionary is incredibly intuitive, there may be problems if we try to create thousands or millions of items simultaneously.

  1. Dictionary needs memory. Millions of objects will eat up the RAM usage.
  2. Dictionary is, in fact, a hash map.

So, the runtime difference between the dictionary and slots may not be noticeable with a few attributes, but as data gets bigger, we will be glad we used slots. Approximately we can save 10% of the run time when accessing attributes.

Example Code:

import timeit


class sample_class(object):
    def __init__(self, *args, **kwargs):
            self.key = 'foo'
            self.value = 'bar'

class sample_class_slots(object):
    __slots__ = ['key','value']
    def __init__(self, *args, **kwargs):
            self.key = 'foo'
            self.value = 'bar'

if __name__ == "__main__":

    time = timeit.timeit('t.key', 'from __main__ import sample_class; t=sample_class()')
    time_slots = timeit.timeit('t.key', 'from __main__ import sample_class_slots; t=sample_class_slots()')

    print("Time without Slots: ", time)
    print("Time with Slots: ", time_slots)

Output:

Time without Slots:  0.0202741
Time with Slots:  0.0200698
Marion Paul Kenneth Mendoza avatar Marion Paul Kenneth Mendoza avatar

Marion specializes in anything Microsoft-related and always tries to work and apply code in an IT infrastructure.

LinkedIn