ProgrammierungBackend Python Entwickler

Was sind __slots__ in Python-Klassen, wozu dienen sie und was sind ihre Einschränkungen?

Bestehen Sie Vorstellungsgespräche mit dem Hintsage-KI-Assistenten

Antwort.

__slots__ ist ein spezielles Attribut einer Klasse, das die zulässigen Attribute einer Instanz einschränkt, Speicher spart und den Zugriff auf Attribute beschleunigt. Die Verwendung von __slots__ ist besonders relevant für eine große Anzahl ähnlicher Objekte.

Hintergrund:

Die Einführung von __slots__ hängt damit zusammen, dass standardmäßig jede Instanz eines Python-Objekts ein Wörterbuch von Attributen (__dict__) hat, was praktisch, aber speicherintensiv ist. Bei einer Million Objekte mit einer kleinen Anzahl von Feldern entsteht ein erheblicher Overhead.

Problem:

Instanzen einer normalen Klasse können dynamisch erweitert werden, was praktisch, aber ineffizient ist. Die Verwendung von __slots__ schränkt das dynamische Hinzufügen neuer Attribute ein, entfernt das instanzspezifische Attribut-Wörterbuch, spart Speicher und beschleunigt den Zugriff.

Lösung:

Definieren Sie eine Liste der erlaubten Felder im Attribut __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' Objekt hat kein Attribut 'z'

Wesentliche Merkmale:

  • Spart Speicher durch den Verzicht auf dict und weakref standardmäßig.
  • Bestimmt eine strenge Liste der erlaubten Felder.
  • Ermöglicht einen schnelleren Zugriff auf Attribute durch vorab zugewiesene Slots (erfordert keine Suche in dict).

Irreführende Fragen.

Kann man eine Instanz einer Klasse mit slots erstellen und dann ein Attribut hinzufügen, das nicht in der Liste ist?

Nein. Beim Versuch, ein Attribut hinzuzufügen, das in der Liste der slots fehlt, wird ein AttributeError ausgelöst. Dies schränkt die Erweiterbarkeit des Objekts ein.

Kann man eine Klasse mit slots erben und neue Felder hinzufügen?

Ja, aber jeder Nachkomme muss seine eigenen slots deklarieren. Dabei werden die Eltern- und aktuellen slots kombiniert. Wenn slots im Nachkommen nicht deklariert werden, hat der Nachkomme jedoch wieder ein dict!

Funktioniert slots für unveränderliche (immutable) Typen?

Ja, aber es müssen zusätzliche Maßnahmen ergriffen werden, um das Slot-Objekt unveränderlich zu machen (zum Beispiel über property ohne Setter).

Typische Fehler und Anti-Pattern

  • slots im Nachkommen nicht deklarieren, was die speichereffiziente Nutzung beeinträchtigt.
  • Erwarten, dass slots bei Mehrfachvererbung funktioniert — es können Konflikte und Fehler auftreten.
  • Der Versuch, Objekte mit Slots mit Standardmethoden zu serialisieren, kann manchmal schwierig sein (zum Beispiel benötigt Pickle dict).

Beispiel aus dem Leben

Negativer Fall

Normale Klasse für einen Punkt:

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

Vorteile:

  • Flexibel — man kann beliebige Attribute hinzufügen.
  • Verständlich für Anfänger.

Nachteile:

  • Der Task-Manager zeigt einen erheblich erhöhten Speicherverbrauch (bis zu +20-30%).

Positiver Fall

Ähnliche Klasse, aber mit 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)]

Vorteile:

  • Bis zu 30% Speicherersparnis bei Millionen von Objekten.
  • Schnellerer Zugriff auf Felder.

Nachteile:

  • Objekte werden unflexibel: es können keine neuen Attribute zur Laufzeit hinzugefügt werden.