Ähnlich wie global ist auch die del-Anweisung ein Quell steter Verwirrung unter Python-Neulingen. Diese Seite versucht, die Missverständnisse auszuräumen.
Zu Beginn: Um del zu verstehen, ist es essentiell, die Paradigmen von Namen und Objekten in Python zu kennen. Die Seite Objekte hilft dabei. In Kürze: Von Variablen zu sprechen, ist in Python ungünstig, besser ist es, man spricht von Objekten, die an Namen gebunden sind.
Es gibt grundsätzlich verschiedene Einsätze für del:
del mit Namen, z.B. del foo. Hiermit wird der Name foo aus dem aktuellen Namensraum entfernt.
Das Objekt, das an foo gebunden war, wird nicht angerührt!
del mit Attributen, z.B. del foo.bar, ruft __delattr__ auf dem Objekt, das an foo gebunden ist, auf. Normalerweise wird damit das Attribut namens bar vom Objekt, das an foo gebunden ist, gelöscht.
del mit Subscript, z.B. del foo[0] oder del foo['bar'], ruft __delitem__ auf dem Objekt, das an foo gebunden ist, auf.
- Dies ist z.B. für Listen oder Dictionaries implementiert und entfernt ein Element mit dem entsprechenden Index bzw. Key aus dem Objekt.
Wer also del verwenden will, um ein Objekt zu "löschen", hat den falschen Ansatz gewählt. Objekte in Python können nicht vom Programmierer gelöscht werden -- sie werden automatisch dealloziert, sobald (bzw. irgendwann nachdem) keine Referenzen mehr auf sie vorhanden sind.
Daher kommt auch die Verwirrung: In einfachen Fällen, in denen ein Name im aktuellen Namensraum die einzige Referenz auf ein Objekt ist, löscht del den Namen, damit auch die Referenz und das Objekt wird dealloziert.
Doch schon ein minimal umfangreicheres Beispiel zeigt, dass del mit dem Objekt nichts anstellt:
1 >>> a = [1, 2, 3]
2 >>> b = a
3 >>> b is a
4 True
5
6 >>> del a
7 >>> b
8 [1, 2, 3]
Wie man sieht, existiert die Liste weiter, nachdem man den Namen a gelöscht hat. Der Test a is b zeigt, dass a und b auf dieselbe Liste zeigen.
Nicht mehr verwendete Namen in Funktionen werden von Python automatisch beim Verlassen entfernt. Es ist also sinnlos vor dem return Statement noch alle lokalen Namen zu löschen.
Verwendungen für del
del kann dennoch sehr viel. Hier eine Liste der sinnvollen Anwendungen:
del foo['bar'] - löscht den Schlüssel 'bar' aus dem dict foo
del foo[0] - löscht das erste Element aus einer Liste
del foo[1:-1] - löscht alle Elemente einer Liste bis auf das erste und letzte
del foo[:] - leert eine Liste
del foo.bar - löscht das Attribut bar von object foo