ProgrammatieBackend Python ontwikkelaar

Wat is __slots__ in Python-klassen, waarom zijn ze nodig en wat zijn de beperkingen?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

__slots__ is een speciale klasse-attribuut dat de set van toegestane attributen van een instantie beperkt, geheugen bespaart en de toegang tot attributen versnelt. Het gebruik van __slots__ is vooral relevant voor een groot aantal vergelijkbare objecten.

Geschiedenis van de kwestie:

De opkomst van __slots__ is gerelateerd aan het feit dat elke instantie van een Python-object standaard een attributenwoordenboek (__dict__) heeft, wat handig is maar veel geheugen kost. Voor een miljoen objecten met een klein aantal velden ontstaat er aanzienlijke overhead.

Probleem:

Instanties van een normale klasse kunnen dynamisch worden uitgebreid, wat handig is, maar inefficiënt. Het gebruik van __slots__ beperkt het dynamisch toevoegen van nieuwe attributen, verwijdert de instantie-attributenwoordenboek, bespaart geheugen en versnelt de toegang.

Oplossing:

Definieer de lijst van toegestane velden in het attribuut __slots__:

class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y p = Point(1, 2) p.z = 3 # AttributeError: 'Point' object heeft geen attribuut 'z'

Belangrijke kenmerken:

  • Bespaart geheugen door de afwezigheid van dict en weakref standaard.
  • Bepaalt een strikte set van toegestane velden.
  • Versnelt de toegang tot attributen dankzij de vooraf toegewezen slots (het vereist geen zoeken in dict).

Vragen met een valstrik.

Kan ik een instantie van een klasse met slots maken en later een attribuut toevoegen dat niet in de lijst staat?

Nee. Bij het proberen toe te voegen van een attribuut dat ontbreekt in de lijst slots wordt een AttributeError opgegooid. Dit legt beperkingen op aan de uitbreidbaarheid van het object.

Kan ik een klasse met slots overerven en nieuwe velden toevoegen?

Ja, maar elke afgeleid klasse moet zijn eigen slots verklaren. In dit geval worden de ouder- en huidige slots samengevoegd. Als er echter geen slots in de afgeleide klasse worden verklaard, krijgt de afstammeling opnieuw een dict!

Werkt slots voor onveranderlijke (immutable) types?

Ja, maar het is nodig om extra maatregelen te nemen om het slot-object onveranderlijk te maken (bijvoorbeeld via property zonder setter).

Typische fouten en anti-patronen

  • Geen slots in de afgeleide klasse verklaren, waardoor het geheugen efficiëntie verloren gaat.
  • Verwachten dat slots werkt in de aanwezigheid van multiple inheritance — er kunnen conflicten en fouten optreden.
  • Proberen om objecten met slots met standaardmethoden te serialiseren is soms moeilijk (bijvoorbeeld pickle vereist dict).

Voorbeeld uit het leven

Negatief geval

Een gewone klasse voor een punt:

class Point: def __init__(self, x, y): self.x = x self.y = y points = [Point(i, i) for i in range(1_000_000)]

Voordelen:

  • Flexibel — je kunt elke attributen toevoegen.
  • Duidelijk voor beginners.

Nadelen:

  • De takenmanager laat een aanzienlijk verhoogd geheugenverbruik zien (tot +20-30%).

Positief geval

Een vergelijkbare klasse, maar met slots:

class Point: __slots__ = ('x', 'y') def __init__(self, x, y): self.x = x self.y = y points = [Point(i, i) for i in range(1_000_000)]

Voordelen:

  • Tot 30% besparing op geheugen bij miljoenen objecten.
  • Snellere toegang tot velden.

Nadelen:

  • Objecten worden inflexibel: nieuwe attributen kunnen niet on-the-fly worden toegevoegd.