Variablen überschreiben

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
Freumel
User
Beiträge: 69
Registriert: Donnerstag 25. Januar 2018, 13:47

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)
einfachTobi
User
Beiträge: 492
Registriert: Mittwoch 13. November 2019, 08:38

In Python werden keine impliziten Kopien erstellt, sondern nur der Verweis.
Näheres in der Doku: https://docs.python.org/3/library/copy.html
Benutzeravatar
__blackjack__
User
Beiträge: 13242
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@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.
Please call it what it is: copyright infringement, not piracy. Piracy takes place in international waters, and involves one or more of theft, murder, rape and kidnapping. Making an unauthorized copy of a piece of software is not piracy, it is an infringement of a government-granted monopoly.
Benutzeravatar
sparrow
User
Beiträge: 4237
Registriert: Freitag 17. April 2009, 10:28

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.
Antworten