Modyfikacja zmiennej
To jakiego typu jest zmienna ma wpływ co się będzie działo przy próbie modyfikacji zawartości. Tak jak wspomniano wcześniej niektóre typy są niemodyfikowalne - co wtedy?
Można to sobie wyobrazić porównując całą sytuację do słoika z jakąś zawartością. Jeden słoik jest zamknięty i nie możemy go otworzyć (dodać czegoś nowego do niego, lub wyjąć z niego jakąś część). Drugi jest w pełni "otwieralny".
W tym pierwszym wypadku jedyną opcją gdy chcemy żeby pod daną etykietą naklejoną na słoik była inna zawartość jest... wziąć nowy słoik (z taką zawartością jakiej potrzebujemy) i przekleić etykietę na ten nowy słoik.
W drugim wypadku można słoik otworzyć i zmienić jego zawartość - a etykieta zostaje w tym samym miejscu.
W przypadku zmiennych jest podobnie. Jeśli docelowy typ jest niemodyfikowalny a chcemy wprowadzić zmiany - oznacza to, że wartość jednej zmiennej KOPIUJEMY (ze zmianami) w nowe miejsce. Dotyczy to wszystkich typów, które są niemodyfikowalne - czyli np. liczb, ciągu znaków (teksty - string), wartości logicznych, krotek.
np.
a = 4 # liczba jest "niemodyfikowalna" sama z siebie
b = a # do zmiennej b jest kopiowana 4 przechowywana pod a
b = b + 2 # do wartości przechowywanej pod b dodawane jest 2
print(a)
print(b)
# wynikiem jest:
# 4
# 6
# wynika to z tego, że b miało wartość SKOPIOWANĄ z a
W Pythonie istnieją też typy, które podlegają modyfikacji - np. listy czy słowniki. W ich wypadku to przekazanie nie robi kopii - przekazywana jest tzw. referencja do obiektu (okropny anglicyzm). Czyli zamiast kopiować wartość przekazywany jest wskaźnik informujący gdzie w pamięci komputera przechowywana jest interesująca nas wartość.
a = [4,2] # liczba jest "niemodyfikowalna" sama z siebie
b = a # zmienna b przechowuje ten sam wskaźnik do obiektu co a
b.pop() # z listy na którą wskazuje b usuwana jest ostatnia wartość
print(a)
print(b)
# wynikiem jest:
# [4]
# [4]
# wynika to z tego, że b i a wskazują na tę samą listę (nie jest robiona kopia)
Skopiowanie wartości
W przypadku gdy mamy do czynienia z obiektem niemodyfikowalnym (np. krotką) jedyne co Python może zrobić to "przekleić" naszą etykietę (zmienną) na nowy obiekt. Jeśli ten pierwotny nie będzie miał na sobie innej etykietki (nie wskazuje na niego inna zmienna) to zostanie on automatycznie usunięty (przez tzw. garbage collector).
Zmiana zawartości
W przypadku gdy obiekt jest modyfikowalny (np. lista) i dołożymy do niej kolejny element zmienna nie będzie musiała przeskoczyć na nowy obiekt z nową zawartością - po prostu zostanie dodany nowy element (zmieni się zawartość obiektu, etykieta będzie wskazywać ten sam obiekt).
... a czemu to istotne?
Powody są co najmniej dwa:
- Należy pamiętać, że gdy zmieniamy jakiś obiekt modyfikowalny na który wskazuje kilka zmiennych to zmienimy wartości dla każdej z nich.
- Tworzenie obiektów (rezerwowanie miejsca w pamięci dla nich) to proces względnie czasochłonny - stąd też proces kopiowania całego obiektu i dodawania do niego jakiegoś dodatkowego elementu (czyli wariant z obiektem niemodyfikowalnym) może spowolnić działanie tworzonej aplikacji.
-> stąd też tak istotne jest świadome dobieranie struktur danych :) .
Co jest modyfikowalne, a co nie?
| typ | modyfikowalny | niemodyfikowalny |
|---|---|---|
| liczba całk. | tak | |
| liczba zmiennop. | tak | |
| wart.log | tak | |
| ciąg znaków | tak | |
| krotka | tak | |
| lista | tak | |
| słownik | tak | |
| zbiór | tak |

