What is the purpose of __slots__?

Asked

Viewed 1,015 times

9

What is this property for __slots__?

Li in the documentation something about "waste of space", but ultimately I didn’t quite understand the purpose of using __slots__.

What it’s for and when I should use it?

  • That’s my question 700 here on the site :p

  • 2

    722 c/ as deleted.

1 answer

13


The __slots__ is a very special attribute for classes - when it is not present, for each new instance of the class, Python creates a new dictionary, but it does not do this if the class defines __slots__.

That is, let’s suppose I want a "Point" class just to save a couple of coordinates (and I can add methods - but it doesn’t change anything here).

In Python I can write (Python 3 - in Python 2 it is necessary to inherit from object):

class Ponto:
    def __init__(self, x=0, y=0):
         self.x = x
         self.y = y
    ...

And this is what we normally know. We can, after instantiating a point, add an attribute z to him:

p = Ponto()
p.z = 0

We know that, as a rule, it is not good practice, but language accepts - and the idea of "consenting adults" Python avoids bad code that adds random attributes to existing class objects.

Now - most of the time you nay you need to add new attributes to your points. And - since each instance of Point has a dictionary to store its attributes, it turns out that an instance that would only use a little more than the space required for two objects of the type float for - maybe about ~80 bytes in total, you also need an entire Python dictionary, albeit zeroed - that’s over 200 bytes.

When the class defines __slots__ Python reserves direct space for the attributes defined in __slots__ the class structure, and nay creates a new dictionary for each instance.

That is, this:

class Ponto:
    __slots__ = ('x', 'y')
    def __init__(self, x=0, y=0):
         self.x = x
         self.y = y

will have the same functionality as the other, but a size of about 80 bytes, not ~300.

On the other hand, trying to create a new attribute results in the error:

Attributeerror: 'Point' Object has no attribute 'z'

In large systems that will have thousands of small objects, this can actually make a difference. You can also imagine other ways to take advantage of this mechanism - for example: Python creates class attributes automatically (dir(Ponto) in the above class will show the attributes x and y), etc...

It is interesting to note that Python’s "builtin" classes as object, int, list, etc... has __slots__ defined - so you cannot create new attributes in instances of this type - but if you inherit any of these, even if you leave the class body blank, you can create new attributes.

namespace = object()
namespace.x = 5

(Attribute Error)

class NS(object): pass
namespace = NS()
namespace.x = 5

(okay)

And it’s also important to keep in mind that if you’re going to create a class hierarchy and use __slots__, each subclass will have to define __slots__ also, otherwise, by default, Python creates the __dict__ for the class.

  • Thank you very much. I had seen the answer in the SOEN and still in the documentation, and had not understood as well as in its explanation +1

Browser other questions tagged

You are not signed in. Login or sign up in order to post.