Da die Leute in den Kommentaren hier und in zwei anderen Fragen, die als Dups markiert sind, alle auf die gleiche Weise verwirrt zu sein scheinen, denke ich, dass es sich lohnt, zusätzlich zu Alex Coventrys eine zusätzliche Antwort hinzuzufügen .
Die Tatsache, dass Alex einen Wert eines veränderlichen Typs wie eine Liste zuweist, hat nichts damit zu tun, ob Dinge geteilt werden oder nicht. Wir können dies mit der id
Funktion oder dem is
Operator sehen:
>>> class A: foo = object()
>>> a, b = A(), A()
>>> a.foo is b.foo
True
>>> class A:
... def __init__(self): self.foo = object()
>>> a, b = A(), A()
>>> a.foo is b.foo
False
(Wenn Sie sich fragen, warum ich object()
anstelle von beispielsweise verwendet habe, 5
um zu vermeiden, dass ich auf zwei ganz andere Probleme stoße, auf die ich hier nicht eingehen möchte. Aus zwei verschiedenen Gründen können vollständig separat erstellte 5
s die sein gleiche Instanz der Nummer 5
. Aber völlig separat erstellte object()
s können nicht.)
Warum a.foo.append(5)
wirkt sich das in Alex 'Beispiel aus b.foo
, a.foo = 5
in meinem Beispiel jedoch nicht? Nun, versuchen a.foo = 5
in Alex Beispiel, und bemerkt , dass es nicht wirkt sich b.foo
dort entweder .
a.foo = 5
macht nur a.foo
einen Namen für 5
. Dies wirkt sich nicht auf b.foo
einen anderen Namen für den alten Wert aus, auf den a.foo
früher Bezug genommen wurde. * Es ist etwas schwierig, ein Instanzattribut zu erstellen, das ein Klassenattribut verbirgt. ** Sobald Sie das erhalten, ist nichts kompliziertes passiert hier.
Hoffentlich ist jetzt klar, warum Alex eine Liste verwendet hat: Die Tatsache, dass Sie eine Liste mutieren können, bedeutet, dass es einfacher ist zu zeigen, dass zwei Variablen dieselbe Liste benennen, und dass es im realen Code wichtiger ist, zu wissen, ob Sie zwei Listen haben oder zwei Namen für dieselbe Liste.
* Die Verwirrung für Leute, die aus einer Sprache wie C ++ kommen, ist, dass in Python Werte nicht in Variablen gespeichert werden. Werte leben im Werteland von sich aus, Variablen sind nur Namen für Werte, und die Zuweisung erstellt nur einen neuen Namen für einen Wert. Wenn es hilft, stellen Sie sich jede Python-Variable als eine shared_ptr<T>
anstelle von a vor T
.
** Einige Benutzer nutzen dies, indem sie ein Klassenattribut als "Standardwert" für ein Instanzattribut verwenden, das von Instanzen festgelegt werden kann oder nicht. Dies kann in einigen Fällen nützlich sein, kann aber auch verwirrend sein. Seien Sie also vorsichtig damit.