Pod tym wiele mówiącym tytułem mamy do rozważenia poniższy kod
x = y x += z
Pytanie: jaka będzie wartość y
po wykonaniu tego kodu?
Programista piszący co nieco w pythonie od razu powinien dostrzec pułapkę i odpowiedź uzależnić od warunków początkowych. Czyli prawidłowa odpowiedź (a raczej pierwsza jej część) będzie brzmiała: to zależy od tego, czym na początku był y
.
Zanim przejdziemy do dogłębnej analizy, polecam obrazek:
Ok, to co my tu mamy. W zasadzie trzy przypadki, które postaram się omówić
Przypadek pierwszy - y jest mutowalny - lista
In [1]: y = [] In [2]: x = y In [3]: x = "tekst" In [4]: print(x, y) ('tekst', [])
Tu wszystko w normie - x
wskazuje na y
, potem zmieniamy wskaźnik na obiekt string, więc y zostaje bez zmian.
Przypadek drugi - y jest mutowalny - lista
In [1]: y = [] In [2]: x = y In [3]: x += ["tekst"] In [4]: print(x, y) (['tekst'], ['tekst'])
Tu dzieje się magia. Nagle y
jest takie samo jak x
mimo, że nie wykonywaliśmy na nim żadnych operacji.
Przypadek trzeci - y jest niemutowalny - string
In [1]: y = "tekst" In [2]: x = y In [3]: x += "inny tekst" In [4]: print(x, y) ('tekstinny tekst', 'tekst')
W pierwszym i trzecim przypadku zachowanie jest "logiczne" - y
nie ulega zmianie. W pierwszym przypadku dlatego, że zmienna x
zaczyna wskazywać na inny obiekt, a w trzecim dlatego, że operacja konkatenacji stringów powoduje stworzenie nowego stringa (stringi w pythonie są niemutowalne).
Drugi przypadek to przykład klasycznej pułapki, o której wspomniałem wcześniej. W momencie dodawania list x
i y
wskazują na ten sam obiekt. Zatem wszystkie operacjie na x
dotyczą również y
.