2012-03-19 12 views
9

Rozważmy następujący kod:Different zachowanie na liście .__ iadd__ i listy .__ add__

>>> x = y = [1, 2, 3, 4] 
>>> x += [4] 
>>> x 
[1, 2, 3, 4, 4] 
>>> y 
[1, 2, 3, 4, 4] 

a następnie rozważyć to:

>>> x = y = [1, 2, 3, 4] 
>>> x = x + [4] 
>>> x 
[1, 2, 3, 4, 4] 
>>> y 
[1, 2, 3, 4] 

Dlaczego istnieje różnica tych dwóch?

(I tak, próbowałem tego szukać).

+4

Co jest ciekawego w twoim ostatnim stwierdzeniu, jest to, że ta funkcjonalność jest wyjaśniona w dokumentacji Pythona: http://docs.python.org/reference/datamodel.html#object.__add__ (z przeszukiwania tych terminów) – jdi

+3

@jdl: Tak, przyznaję, że przeoczyłem to. –

Odpowiedz

20

__iadd__ mutuje listę, natomiast __add__ zwraca nową listę, czego dowodem.

Najpierw próbuje się zadzwonić pod numer __iadd__, a po tym, wywołanie __add__ następuje po przypisaniu (patrz komentarz Svena dotyczący drobnej korekty). Od list ma __iadd__ to robi to trochę magii mutacji.

+1

Jeśli chcesz uzyskać więcej szczegółowych informacji na temat tego zachowania i innych informacji na temat tego, dlaczego Python jest taki, jaki jest - gorąco poleciłbym [Python epiphanies talk] (http://pyvideo.org/video/613/python-epiphanies) z PyCon 2012. To doprowadzi cię do "ha!"! chwile. –

+0

@S Singh, jeśli otrzymasz odpowiedź, wybierz odpowiedź jako zaakceptowaną odpowiedź i przeprowadź proces pracy. W przeciwnym razie to pytanie zostanie pokazane jako bez odpowiedzi. – Nilesh

+1

Ta odpowiedź jest nieco myląca: Przypisanie jest zawsze wykonywane, niezależnie od tego, czy wywoływane jest '__iadd __()' lub '__add __()'. 'list .__ iadd __()' po prostu zwraca 'self', więc przypisanie nie ma żadnego skutku poza renderowaniem docelowej nazwy lokalnej do bieżącego zakresu. –

3

Pierwsza mutuje listę, a druga ponownie wiąże nazwę.

Powiązane problemy