Using slots in your classes to prevent attribute creation at runtime

First published:

Last Edited:

Number of edits:

<p> The first time I heard of slots, I thought they were referring to the <a class="wikilink" href="/qt/"> Qt </a> idea of signals and slots. It turns out that <a class="wikilink" href="/python/"> Python </a> defines its own slots and are completely unrelated to those of Qt. Let's quickly see what they can do for us: </p> <pre class="codehilite"><code class="language-python">class Slot: __slots__ = ['attr1', 'attr2'] </code></pre> <pre class="codehilite"><code class="language-pycon">&gt;&gt;&gt; s = Slot() &gt;&gt;&gt; s.attr1 = 1 &gt;&gt;&gt; s.attr2 = 2 &gt;&gt;&gt; s.attr3 = 3 ... AttributeError: 'Slot' object has no attribute 'attr3' </code></pre> <p> I think it is quite clear what slots are meant to do: they define the attributes that a class has and it prevents you from creating new attributes later on. We can keep on experimenting. Slots are used when the class is defined, therefore, we can have something like this: </p> <pre class="codehilite"><code class="language-python">class Slot: __slots__ = ['attr1', 'attr2'] attr3 = 3 </code></pre> <pre class="codehilite"><code class="language-pycon">&gt;&gt;&gt; s = Slot() &gt;&gt;&gt; s.attr3 3 &gt;&gt;&gt; s.attr3 = 4 ... AttributeError: 'Slot' object attribute 'attr3' is read-only </code></pre> <p> You can mix slots and class attributes, but as expected, only those defined in the <code> __slots__ </code> iterable are writable. </p> <h2> Why Using Slots </h2> <p> Using slots feels slightly <em> unpythonic </em> , it somehow removes the dynamic part that makes it so attractive for many of us. However, I found a very clear use case when you are developing code to work with instruments: </p> <p> Imagine you have a camera in which you can set the exposure time. You develop a class, and define an attribute <code> exposure </code> . Another day, or another person, grabs your code, and while fiddling, uses <code> exp_time </code> instead of exposure. No error will appear since <a class="wikilink" href="/python/"> Python </a> allows you to define attributes at runtime, but it is for sure an unwanted behavior. If you define <code> __slots__ </code> , you will be sure that mistake can't happen. This is can also be avoided if you opt for <a class="wikilink" href="/functional_control/"> functional control </a> instead of <a class="wikilink" href="/imperative_control/"> imperative control </a> . </p> <p> Another reason to use slots is because it lowers the memory consumption of your programs. Python's objects store attributes in a dictionary, which may be memory inefficient if you are going to create a lot of objects of the same class with a limited set of attributes. A personal example: </p> <p> I was simulating <a class="wikilink" href="/brownian_diffusion/"> Brownian Diffusion </a> of multiple particles, each one was an object of class <code> Particle </code> . Each particle had a limited number of attributes, but I needed to create millions of them. At the time I didn't know the slots possibility, and had to work around the limits of my computer, but I now know I could have had a much better performing program. </p> <h2> Inheritance </h2> <p> Inheritance with classes that define slots is an interesting pattern. Let's quickly see what I am talking about: </p> <pre class="codehilite"><code class="language-python">class Slot: __slots__ = ['var1', 'var2'] class NewSlot: pass </code></pre> <p> And if we try out the <code> NewSlot </code> class: </p> <pre class="codehilite"><code class="language-pycon">&gt;&gt;&gt; s = NewSlot() &gt;&gt;&gt; s.var3 = 3 &gt;&gt;&gt; s.var3 3 </code></pre> <p> We see that it gets the dynamic attribute assignment of the normal Python objects. However, we can also do the following: </p> <pre class="codehilite"><code class="language-python">class NewSlot: __slots__ = ['var3'] </code></pre> <p> In which case: </p> <pre class="codehilite"><code class="language-pycon">&gt;&gt;&gt; s = NewSlot() &gt;&gt;&gt; s.var1 = 1 &gt;&gt;&gt; s.var3 = 3 &gt;&gt;&gt; s.var4 = 4 ... AttributeError: 'Slot' object has no attribute 'var4 ' </code></pre> <h2> Why Not Using Slots </h2> <p> If there are reasons to use slots, there should also be reasons not to use them. First, it forces you to repeat yourself: you need to define attributes both in the <code> __slots__ </code> and in the class. </p>

Backlinks

These are the other notes that link to this one.

Nothing links here, how did you reach this page then?

Comment

Share your thoughts on this note. Comments are not public, they are messages sent directly to my inbox.
Aquiles Carattino
Aquiles Carattino
This note you are reading is part of my digital garden. Follow the links to learn more, and remember that these notes evolve over time. After all, this website is not a blog.
© 2026 Aquiles Carattino
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License
Privacy Policy