Objekte und ihre Kopien mit =

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
Lasse
User
Beiträge: 112
Registriert: Donnerstag 3. Februar 2011, 18:25

Ich habe ein klitzekleines Problem (genau 5 Zeilen lang :mrgreen: ) Wenn ich dieses Beispiel ausführe und A_Object.a am Ende anzeige ist es auch 2. Das ist sehr nützlich für mein Programm, aber kann man sich darauf verlassen?

Code: Alles auswählen

class A:
    a = 1
A_Object = A()
Y = A_Object
Y.a = 2
Soweit ich weiß hat dieses Verhalten etwas mit Speichersparen und das Python Objekte dann gerne zusammenlegt zu tun.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du hast es zwar etwas plump ausgedrückt, aber im Kern stimmt das schon so. Du bindest in Python Objekte an Namen. Mit `A()` erzeugst Du ein neues Objekt der Klasse A, welches Du dann nur an verschiedene Namen bindest. Insofern ist das wenig überraschend. Du kannst ja mal folgendes eingeben:

Code: Alles auswählen

A_Object is Y
Das Ergebnis bestätigt, dass es sich um ein und dasselbe Objekt handelt.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Lasse hat geschrieben:Soweit ich weiß hat dieses Verhalten etwas mit Speichersparen und das Python Objekte dann gerne zusammenlegt zu tun.
Nein. Die Semantik von `=` ist eine andere als du denkst: Es werden _nie_ Kopien angefertigt, sondern die Objekte auf der rechten Seite werden an den Namen auf der linken Seite gebunden.

Und bevor du darueber stolperst: Mit `Y.a = 2` erstellst du einen neuen Namen _in der Instanz_ du veraenderst nicht den Namen `a` in der Klasse. `A.a` ist danach immernoch 1.

Und dann noch mit veraenderbaren Objekten, damit es auch richtig lustig wird:

Code: Alles auswählen

In [2]: class A:
   ...:     a = []
   ...:    

In [3]: a = A(); b = A(); c = A()

In [4]: a.a = a.a + [1,2]; b.a.extend([3,4]) ; c.a += [5,6]

In [5]: a.a, b.a, c.a, A.a
Out[5]: ([1, 2], [3, 4, 5, 6], [3, 4, 5, 6], [3, 4, 5, 6])
Lasse
User
Beiträge: 112
Registriert: Donnerstag 3. Februar 2011, 18:25

Danke die Antworten, jetzt weiß ich, dass es immer funktioniert,ebenauch das ich die Klasse selbst nicht verändere, wäre sonst auch ziemlich unpraktisch. :mrgreen:
Antworten