Identität unter Python

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
six.stars.far
User
Beiträge: 3
Registriert: Dienstag 9. Dezember 2014, 15:42

Hallo zusammen!

Ich habe eine Frage zum Verständnis der Identität. Ich arbeite mit python 3.4.0.

Folgendes habe ich in die Python-Shell eingegeben:

Code: Alles auswählen

>>> x = 1
>>> y = 1
>>> print(id(x), id(y))
10455040 10455040
oder mit anderen Worten:

Code: Alles auswählen

>>> id(x) == id(y)
True
Ein zweites Beispiel:

Code: Alles auswählen

>>> a = -6
>>> b = -6
>>> print(id(a), id(b))
140571534466864 140571533906192
>>> id(a) == id(b)
False
Ein drittes Beispiel:

Code: Alles auswählen

>>> c = -1
>>> d = -1
>>> print(id(c), id(d))
10454976 10454976
>>> id(c) == id(d)
True
Habe ich etwas falsch gemacht oder falsch verstanden? Das zweite Beispiel hat mich überrascht, weil auf einmal keine Identität zwischen a und b gegeben war. Also habe ich es mit einer anderen negativen Zahl versucht und immer noch war keine Identität vorhanden. Dann habe ich die Python-Shell neu gestartet und das dritte Beispiel probiert: jetzt konnte ich das Phänomen von Beispiel 2 nicht mehr nachvollziehen. Gibt es dafür einen Erklärung?

Ich habe eine ganz allgemeine Frage: Wieso stellt Python automatisch Identität zwischen zwei Objekten her, wenn die Werte zweier Variablen gleich sind? Ich finde dieses Phänomen überraschend. Ich hätte nicht erwartet, dass bei zwei einfachen Zuordnungen wie "g = 5" und "h = 5" automatisch Identität hergestellt wird.

Vielen Dank für die Rückmeldungen!
BlackJack

@six.stars.far: Zwei Objekte mit dem gleichen Wert müssen nicht die gleiche Identität haben. Dass das bei Zahlen und Zeichenketten manchmal der Fall ist und manchmal nicht, ist ein Implementierungsdetail. Weil Zahlen und Zeichenketten nicht verändert werden können, machte es nichts aus wenn Python da falls möglich die *selben* Objekte verwendet. Das einzige wo wirklich garaniert ist, dass man das selbe Objekt unter zwei Unterschiedlichen Namen hat, ist die direkte Zuweisung. Also nach ``a = b`` gilt immer ``id(a) == id(b)`` oder anders ausgedrückt ``a is b``.
six.stars.far
User
Beiträge: 3
Registriert: Dienstag 9. Dezember 2014, 15:42

Vielen Dank für die schnelle Antwort.

Was darf ich mir denn unter "Implementierungsdetail" vorstellen? Hat dieses Detail irgendwelche Auswirkungen, die ich beim programmieren unbedingt beachten sollte?

Du sprachst davon, dass Zahlen und Zeichenketten nicht veränderlich sind. So weit, so gut. Darf ich dann umgekehrt daraus schließen, dass veränderliche Objekte trotz "gleichem" Inhalts nie dieselbe Identität haben?

Die beiden Beispiele, das ich gerade durchlaufen habe, sprächen für diese Annahme:

Code: Alles auswählen

>>> l1 = ['Berlin', 'München', 'Frankfurt']
>>> l2 = ['Berlin', 'München', 'Frankfurt']
>>> l1 is l2
False
>>> print(id(l1), id(l2))
139753645716488 139753645717384

Code: Alles auswählen

>>> s1 = {'Berlin', 'München', 'Frankfurt'}
>>> s2 = {'Berlin', 'München', 'Frankfurt'}
>>> s1 is s2
False
>>> print(id(s1), id(s2))
139753646529896 139753645705032
six.stars.far
User
Beiträge: 3
Registriert: Dienstag 9. Dezember 2014, 15:42

PS: Obwohl ich mir gerade nicht sicher bin, ob Mengen veränderlich sind oder nicht...
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

six.stars.far hat geschrieben:Was darf ich mir denn unter "Implementierungsdetail" vorstellen? Hat dieses Detail irgendwelche Auswirkungen, die ich beim programmieren unbedingt beachten sollte?
Im Wesentlichen sollte dir klar sein, dass man "normale" Vergleiche mit == durchführt. Nur wenn es explizit um Objektidentität geht, dann solltest du is einsetzen. Das wäre zum Beispiel bei einem Vergleich mit einem Singleton wie None der Fall (if value is None:).
BlackJack

@six.stars.far: Implementierungsdetail heisst das das etwas ist auf das man sich nicht verlassen darf, weil das von der Sprachspezifikation nicht garantiert wird. Das sollte keine Auswirkungen auf ansonsten korrekte Programme haben. Man sieht halt manchmal bei Programmieranfängern so etwas wie ``if a is 42:`` und das ”funktioniert” dann zufällig bei einer Python-Implementierung die kleine Integerwerte cached und wenn möglich die selben Objekte verwendet. Das Programm ist an der Stelle aber fehlerhaft, weil diese Optimierung nirgends garantiert wird.

Veränderbare Objekte haben nur die selbe Identität wenn es sich tatsächlich um das selbe Objekt handelt. Wenn man solche Objekte durch Literale erstellt, dann sind das natürlich jedes mal andere Objekte, denn sonst könnte man damit nicht sinnvoll programmieren.

Mengen sind veränderbar. Die haben doch Methoden wie `add()` und `remove()`.
Antworten