Seite 1 von 1

Variablen überschreiben

Verfasst: Montag 22. Juni 2020, 15:03
von Freumel
Hallöchen,

ich bin auf folgendes "Problem" gestoßen (ich verstehe einfach das "Warum" nicht und wie man hier arbeitet). Man nehme folgende Situation:

Code: Alles auswählen

a = 7
b = a
b = 99

print(a)
print(b)
Ausgabe:

Code: Alles auswählen

7
99
Passt für mich. Finde ich toll und erwarte ich so.

Nun wandle ich das Szenario um:

Code: Alles auswählen

class Test:
    def __init__(self, a):
        self.__a = a
    def getA(self):
        return self.__a
    def setA(self,a):
        self.__a = a

a = Test(7)
b = a
b.setA(99)

print(a.getA())
print(b.getA())
Ausgabe:

Code: Alles auswählen

99
99
Hat bestimmt Sinn, ich verstehe aber nicht ganz das "Warum".
=> Warum haben sich sowohl a, als auch b verändert, obwohl ich die set Methode nur bei b anwende?
Ich vermute (und hier könnt ihr mich gerne korrigieren), dass das Objekt (bzw die Klasse) inklusive Zeiger auf den Speicherort zu b kopiert wird und daher sowohl die Variablen a und b in der set Methode angepasst werden. Ist das so ungefähr richtig interpretiert?

Wie würde man vorgehen wenn man das vor hat, was ich im Code versuche zu tun (um das Ziel zu spezifizieren: Ich möchte eine Variable b mit gleichen Properties wie a erzeugen und anschließend einen Wert verändern ohne dabei a zu verändern)

Re: Variablen überschreiben

Verfasst: Montag 22. Juni 2020, 15:19
von einfachTobi
In Python werden keine impliziten Kopien erstellt, sondern nur der Verweis.
Näheres in der Doku: https://docs.python.org/3/library/copy.html

Re: Variablen überschreiben

Verfasst: Montag 22. Juni 2020, 17:06
von __blackjack__
@Freumel: Du hast halt nur *ein* Objekt das Du an zwei Namen bindest — `a` und `b`. Es haben sich also nicht sowohl `a` und `b` geändert, weil es da keinerlei Unterschied gibt beim Objekt.

Im ersten Fall veränderst Du kein Objekt sondern bindest einen Namen an ein komplett anderes Objekt. Das hat keinen Einfluss auf das Objekt das vorher mal an den Namen gebunden war.

Kleine Korrektur des Beispiels:

Code: Alles auswählen

class Test:
    def __init__(self, a):
        self.a = a


a = Test(7)
b = a
b.a = 99

print(a.a)
print(b.a)
In Python schreibt man keine trivialen Getter und Setter. Insbesondere wenn es beides gibt ist das doch völlig unsinnig, denn das ist das Attribut effektiv öffentlich.

Es gibt auch kein ”private”. Die doppelten führenden Unterstriche sind *nicht* ”private”. Für nicht-öffentliche Attribute verwendet man *einen* führenden Unterstrich.

Re: Variablen überschreiben

Verfasst: Montag 22. Juni 2020, 17:07
von sparrow
Oder anders Ausgedrückt:
Du bindest eine Instanz von Test an den Namen a. Unf anschließend bindest du die selbe Instanz an den Namem b. Es handelt sich aber um das selbe Objekt.