Ponieważ ludzie w komentarzach tutaj iw dwóch innych pytaniach oznaczonych jako dupki wydają się być zdezorientowani w ten sam sposób, myślę, że warto dodać dodatkową odpowiedź oprócz odpowiedzi Alexa Coventry'ego .
Fakt, że Alex przypisuje wartość typu zmiennego, takiego jak lista, nie ma nic wspólnego z tym, czy rzeczy są udostępniane, czy nie. Widzimy to za pomocą id
funkcji lub is
operatora:
>>> 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
(Jeśli zastanawiasz się, dlaczego użyłem object()
zamiast, powiedzmy, 5
aby uniknąć napotkania dwóch innych problemów, których nie chcę tutaj omawiać; z dwóch różnych powodów, całkowicie oddzielnie utworzone 5
pliki mogą ostatecznie stać się to samo wystąpienie liczby 5
. Ale całkowicie oddzielnie utworzone object()
s nie mogą).
Dlaczego więc a.foo.append(5)
w przykładzie Alexa ma to wpływ b.foo
, a a.foo = 5
w moim nie? Dobrze, spróbuj a.foo = 5
na przykład Alexa, i zauważ, że nie wpływa on b.foo
tam albo .
a.foo = 5
po prostu tworzy a.foo
nazwę dla 5
. To nie ma wpływu b.foo
, ani żadna inna nazwa starej wartości, a.foo
do której się odnosiliśmy. * To trochę skomplikowane, że tworzymy atrybut instancji, który ukrywa atrybut klasy, ** ale kiedy już to zdobędziesz, nic skomplikowanego nie jest dzieje się tutaj.
Mamy nadzieję, że teraz jest oczywiste, dlaczego Alex użył listy: fakt, że możesz zmutować listę, oznacza, że łatwiej jest pokazać, że dwie zmienne nazywają tę samą listę, a także oznacza, że w prawdziwym kodzie ważniejsze jest, aby wiedzieć, czy masz dwie listy, czy dwie nazwy dla tej samej listy.
* Zamieszanie dla ludzi wywodzących się z języka takiego jak C ++ polega na tym, że w Pythonie wartości nie są przechowywane w zmiennych. Wartości same w sobie żyją na gruncie wartości, zmienne są tylko nazwami wartości, a przypisanie tworzy po prostu nową nazwę wartości. Jeśli to pomoże, pomyśl o każdej zmiennej Pythona jako o shared_ptr<T>
zamiast a T
.
** Niektóre osoby wykorzystują to, używając atrybutu class jako „wartości domyślnej” atrybutu instancji, który instancje mogą lub nie mogą być ustawiane. Może to być przydatne w niektórych przypadkach, ale może też być mylące, więc bądź ostrożny.