Slots



Erzeugung von dynamischen Attributen verhindern

Computer Slots Die Attribute eines Objektes werden in einem Dictionary "__dict__" gespeichert. Wie jedes andere Dictionary auch, ist die Anzahl der Elemente nicht begrenzt. In anderen Worten: man kann weitere Elemente einem Dictionary zufügen, nachdem es definiert worden ist. Aus diesem Grund kann man auch dem Object einer Klasse, so wie wir sie bisher definiert hatten, beliebige weitere Attribute zufügen.

>>> class A(object):
...     pass
... 
>>> a = A()
>>> a.x = 66
>>> a.y = "dynamically created attribute"
Das Dictionary, welches die Attribute von "a" enthält, kann folgendermaßen angesprochen werden:
>>> a.__dict__
{'y': 'dynamically created attribute', 'x': 66}
Einige werden sich sicherlich gewundert haben, dass man zu den bisher von uns definierten Klassen, dynamisch Attribute hinzufügen kann, während es bei den meisten built-in-Klassen, wie zum Beispiel 'int' oder 'list', nicht möglich ist:
>>> x = 42
>>> x.a = "not possible to do it"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'int' object has no attribute 'a'
>>> 
>>> lst = [34, 999, 1001]
>>> lst.a = "forget it"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'list' object has no attribute 'a'
Ein Dictionary zu benutzen um Attribute zu speichern ist eine passende Möglichkeit. Daraus folgt aber auch, dass für Objekte mit wenigen Instanz-Attributen, trotzdem viel Speicher benötigt wird. Der Speicher-Bedarf wird dann kritisch, wenn viele Instanzen erstellt werden. Hier kommen die s.g. Slots ins Spiel. Mit Slots haben wir die Möglichkeit dem Speicher-Konsum entgegenzuwirken. Statt eines dynamischen Dictionary, stellen Slots eine statische Struktur zur Verfügung, die weiteres Hinzufügen von Attributen verhindert, sobald eine Instanz erstellt wurde.

Um Slots zu benutzen, müssen Sie die Liste __slots__ definieren. Die Liste muss alle Attribute beinhalten, die Sie benutzen wollen. Im folgenden Beispiel demonstrieren wir eine Klasse, dessen Slot-Liste nur den Namen des Attributes "val" enthält.
class S(object):

    __slots__ = ['val']

    def __init__(self, v):
        self.val = v


x = S(42)
print(x.val)

x.new = "not possible"
Wenn wir das Programm starten werden wir bemerken, dass es nicht möglich ist ein weiteres Attribut dynamisch zu erzeugen. Beim Versuch das Attribut "new" zu erzeugen stoßen wir auf einen Fehler:
42
Traceback (most recent call last):
  File "slots_ex.py", line 12, in <module>
    x.new = "not possible"
AttributeError: 'S' object has no attribute 'new'

Wie bereits erwähnt, helfen Slots dabei, den Speicher nicht mit der Bildung unnötiger Objekte zu verschwenden. Seit Python 3.3 ist dieser Vorteil aber nicht mehr so besonders beeindruckend. Mit der Einführung von Python 3.3 werden Key-Sharing-Dictionaries für die Speicherung von Objekten benutzt. Die Attribute der Instanzen sind in der Lage, einen Teil ihres genutzten Speichers mit anderen zu teilen. So kann der Speicher-Bedarf von Programmen gesenkt werden, die viele Instanzen von Klassen erstellen, die nicht ,,built-in'' sind.