Klassenattribute

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
Martinuk
User
Beiträge: 5
Registriert: Freitag 21. Februar 2020, 07:51

Hallo,

und zwar habe ich eine Frage zu den folgenden Beispielen

Code: Alles auswählen

class P:

    def __init__(self, x):
        self._x = x

    def my_func(self):
        y = self._x
        y = 6
        return y
    
obj = P(5)
out = obj.my_func()
print(out)
print(obj._x)

5
6
Dann bekomme ich für y = 6 zurück und die Objekteigenschaft x = 5

Wenn ich nun das gleiche Prinzip auf ein 'dict' anwende dann ändert sich das ganze wie folgt

Code: Alles auswählen

class P:

    def __init__(self, x):
        self._x = {'A': 0, 'B': 0, 'C': 0}

    def my_func(self):
        y = self._x
        y['A'] = 10
        return y
    
obj = P(5)
out = obj.my_func()
print(out)
print(obj._x)

{'A': 10, 'B': 0, 'C': 0}
{'A': 10, 'B': 0, 'C': 0}
Nun hat sich auch die Objekteigenschaft x geändert. Aber warum?
Anstatt eine Kopie für y anzulegen sieht es so aus als wäre y eine Art Pointer auf x und damit ändern sich nun beide Variablen. Zuvor war das aber nicht der Fall.

Kann mir bitte jemand helfen zu verstehen warum und wie ich hier am besten weitermache? Danke.
Martinuk
User
Beiträge: 5
Registriert: Freitag 21. Februar 2020, 07:51

Update, auf der Seite https://www.w3schools.com/python/python ... naries.asp habe ich folgendes zu dem Thema gefunden.

You cannot copy a dictionary simply by typing dict2 = dict1, because: dict2 will only be a reference to dict1, and changes made in dict1 will automatically also be made in dict2.

There are ways to make a copy, one way is to use the built-in Dictionary method copy().
Another way to make a copy is to use the built-in method dict().
Sirius3
User
Beiträge: 18219
Registriert: Sonntag 21. Oktober 2012, 17:20

Du denkst in die falsche Richtung. Variablennamen sind nur Verweise auf Objekte. Im ersten Beispiel hast Du ein Objekt für die Zahl 5 und dann verweist y auf ein Objekt der Zahl 6. Die 5 hat sich dadurch nicht geändert; wäre auch doof, wenn in jeder Rechnung die 5 durch 6 ersetzt würde.
Benutzeravatar
__blackjack__
User
Beiträge: 13926
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Und noch als Amerkungen: Von den im Titel des Themas erwähnten Klassenattributen ist hier nichts zu sehen. Das sind (Daten-)Attribute die auf der *Klasse* definiert sind.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
Benutzeravatar
sparrow
User
Beiträge: 4506
Registriert: Freitag 17. April 2009, 10:28

@Martinuk:

Was du bei deinem ersten Beispiel machst, hat - wie __blackjack__ bereits gesagt hat, nichts mit Klassenatrributen zu tun. Was du tust ist im Prinzip das hier:

Code: Alles auswählen

>>> x = 5
>>> y = x
>>> y = 6
>>> print(y)
6
Und erwartest du ja auch nicht, dass die Ausgabe 5 ist, oder? Denn du bindest ja den neuen Wert 6 an den Namen 'y'.

Das zweite Beispiel sieht ohne den Klassenumbau so aus:

Code: Alles auswählen

>>> x = {'A': 0, 'B': 0, 'C': 0}
>>> y = x
>>> y['A'] = 10
>>> print(y)
{'A': 10, 'B': 0, 'C': 0}
Da bindest du das Objekt, das an den Namen x gebunden ist (in diesem Fall ein dict) zusätzlich an den Namen y.
Antworten