Speicherung von Variablen in Python, Expertenfrage?
Eine Frage zu dem Übergeben, bzw. Verknüpfen von Variablen.
Gibt es in Python etwas sowas wie Pointer, die nicht für den Nutzer verfügbar sind sondern nur innertechnisch existieren?
Das Problem: ich habe eine Objekt1 wo eine Position einer von einem anderen Objekt2, aber gleiche Klasse, übergeben wird (nur im __init__) und diese Variable in dem Obejekt1 gespeichert wird. Ich zeichne dann aus den beiden Objekten einen Punkt anhand der gespeicherten Positions-Vektoren. Nun das Problem: wenn ich die Variable des Objekt2 "ändere", "ändert" sich auch der Wert des Objekt1 obwohl ich den übergebenen Positionswert NIE mehr aktualisiert habe, somit überschneiden sich die beiden Punkte...
Nun das kuriose: wenn ich bei der Übergabe der Positionsvariable vom Objekt2 zu Objekt1 bei der SPeicherung nicht self.pos = pos SONDERN self.pos = pos+pygame.math.Vector2(0,0) sage, ändert sich dafür der Positionswert des Objekt1 NICHT MEHR... Genau das will ich ja.
Nun meine Theorie warum das so sein könnte... Wen ich self.pos = pos sage speichere ich die Speicheradresse von der Variable des Objekt2, ich referiere quasi darauf. Immer wenn er die Variable im Objekt1 braucht geht er zur Speicheradresse und zieht die Variable aus dem RAM raus. Wenn ich aber self.pos = pos+pygame.math.Vector2(0,0) sage, erzwinge ich durch +pygame.math.Vector2(0,0), dass er die Variabel speichert und nicht nur die Speicheradresse...
Ist meine Thorie richtig? Wenn ja, gibt es noch andere Wege nicht nur die Speicheradresse sondern den Variablen Wert zu speichern?
Danke an jeden der sich das durchgelesen hat xD
LG
Edit: Weil ja spezielle Module auf C (und C Pointer besitzt) aufbauen, könnte ich mir es so vorstellen...
2 Antworten
Ja, wird aber hier nicht Pointer sondern Referenz genannt.
Durch Zuweisungen mit = werden nicht die Objekte kopiert, sondern nur ihre Referenzen. Du hast dann zwei Namen für dasselbe Objekt.
pos+pygame.math.Vector2(0,0) erzeugt ein neues Objekt (mit den gleichen Koordinaten)
Schau dir mal die Doku (Stichwort copy, deep copy, shallow copy) an.
Dasselbe gilt auch für andere Objekte (hier Listen):
>>> a = [1,2,3,4]
>>> b=a
>>> b[2] = 17
>>> print(a)
[1, 2, 17, 4]
Auf diesen Zusammenhang stößt man aber eigentlich schon ziemlich am Anfang einer jeden Python-Karriere. Vgl. hinzugefügtes Codebeispiel
Joa... ich komischerweise nicht xD
Eine Frage noch: in welchen Fällen kopiert man das Objekt und übergibt nicht die Speicheradresse. Also in welchen Fällen ist das von großer Notwendigkeit?
Wenn du die Kopie verändern, aber das Original beibehalten willst.
Ich bin das erste Mal reingefallen als ich ein 2 dimensionales Array machen wollte:
>>> a = [0] * 5
>>> aa = [a] * 5
>>> print(aa)
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
Soweit so gut, aber dann:
>>> aa[0][1] = 1
>>> print(aa)
[[0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0], [0, 1, 0, 0, 0]]
Das ist aber in Java nicht anders, obwohl es dort auch keine expliziten Pointer (und vor allem keine Pointerarithmetik) gibt.
muss man sich in C++/C um die Referenzen selber kümmern, ist „normales“ übergeben von Variablen auch nur Referenzen oder in C++ 1:1 Kopie des Objektes?
Mein C/C++ ist zu lange her (> 20 Jahre). Da musste man mit & und * herumzaubern, wenn man Referenzen meinte. Müsste ich mich wieder reinfuchsen.
Wenn du in Python ein Objekt an eine Funktion übergibst, wird dessen Referenz (als Wert) übermittelt. Das heißt, wenn das Objekt in der Funktion seinen Zustand ändert, dann gilt das auch für das Objekt außerhalb der Funktion.
class Person:
def __init__(self, name):
self.name = name
def change_name(person, name):
person.name = name
tim = Person("Tim")
change_name(tim, "Tom")
print(tim.name) # Tom
Sobald du allerdings eine Zuweisung vornimmst, zeigt der Parameter auf ein neues Objekt. Das Objekt außen wird nicht mehr verändert.
class Person:
def __init__(self, name):
self.name = name
def change_name(person, name):
person = Person(name)
tim = Person("Tim")
change_name(tim, "Tom")
print(tim.name) # Tim
Wow ich bin so gut xD
Danke!!!