Zmienialne i niezmienialne w Pythonie
Ten artykuł wyjaśnia zmienialność i niezmienialność w Pythonie.
YouTube Video
Zmienialne i niezmienialne w Pythonie
"Zmienialne" i "niezmienialne" odnoszą się do zdolności obiektu do zmiany stanu. Zrozumienie tego pomaga unikać nieoczekiwanych błędów i efektywnie zarządzać pamięcią.
Co to jest Zmienialne?
Zmienialne obiekty mogą zmieniać swój stan wewnętrzny po utworzeniu.
Główne zmienialne typy danych
list
dict
set
- Klasy definiowane przez użytkownika (jeśli ich atrybuty mogą być modyfikowane)
Przykład: Modyfikacja listy
1numbers = [1, 2, 3]
2numbers[0] = 100
3print(numbers) # [100, 2, 3]
Lista jest obiektem zmienialnym, a jej elementy mogą być dowolnie modyfikowane.
Co to jest Niezmienialne?
Niezmienialne obiekty nie mogą być zmieniane po ich utworzeniu. Próba ich zmiany skutkuje utworzeniem nowego obiektu.
Główne niezmienialne typy danych
int
float
str
tuple
bool
frozenset
Przykład: Modyfikacja napisu
1text = "hello"
2# text[0] = "H" # TypeError: 'str' object does not support item assignment
3
4text = "H" + text[1:] # Creates a new string
5print(text) # "Hello"
Napisy są niezmienialne, więc nie można ich częściowo modyfikować.
Porównanie zmienialnego i niezmienialnego
1# Mutable example
2a = [1, 2, 3]
3b = a
4b[0] = 100
5print(a) # [100, 2, 3] -> a is also changed
6
7# Immutable example
8x = 10
9y = x
10y = 20
11print(x) # 10 -> x is unchanged
Jak pokazano w powyższym przykładzie, zmienialne obiekty są współdzielone przez referencję, więc mogą wpływać na inne zmienne. Z drugiej strony, obiekty niemutowalne tworzą nowe instancje po przypisaniu, pozostawiając pierwotną wartość nienaruszoną.
Analizowanie wewnętrznego zachowania za pomocą id()
W Pythonie możesz użyć funkcji id()
, aby sprawdzić identyfikator obiektu. Identyfikator obiektu jest podobny do adresu pamięci.
1# Immutable int behavior
2a = 10
3print(id(a)) # e.g., 140715920176592
4a += 1
5print(id(a)) # e.g., 140715920176624 -> ID has changed
6
7# Mutable list behavior
8b = [1, 2, 3]
9print(id(b)) # e.g., 2819127951552
10b.append(4)
11print(id(b)) # Same ID -> only the content has changed
Jak pokazano, dla typów niemutowalnych tworzony jest nowy obiekt, podczas gdy typy mutowalne są modyfikowane w miejscu.
Funkcje i ostrożność przy obiektach mutowalnych i niemutowalnych
Przy przekazywaniu obiektu mutowalnego do funkcji, oryginalne dane mogą zostać zmodyfikowane.
Przykład: Funkcja modyfikująca listę
1def modify_list(lst):
2 lst.append(100)
3
4my_list = [1, 2, 3]
5modify_list(my_list)
6print(my_list) # [1, 2, 3, 100]
Przykład: Funkcja modyfikująca liczbę
Z drugiej strony, próba modyfikacji obiektu niemutowalnego skutkuje utworzeniem nowego obiektu.
1def modify_number(n):
2 n += 10
3
4my_number = 5
5modify_number(my_number)
6print(my_number) # 5 -> unchanged
Rozważania praktyczne
Unikaj używania mutowalnych obiektów jako domyślnych argumentów
1# Bad example
2def add_item(item, container=[]):
3 container.append(item)
4 return container
5
6print(add_item(1)) # [1]
7print(add_item(2)) # [1, 2] -> unintended behavior
8
9# Good example
10def add_item(item, container=None):
11 if container is None:
12 container = []
13 container.append(item)
14 return container
Ponieważ domyślne argumenty są oceniane tylko raz podczas definiowania funkcji, używanie obiektów mutowalnych może prowadzić do nieoczekiwanych skutków ubocznych.
Podsumowanie
Aby dogłębnie zrozumieć zmienne i typy danych w Pythonie, kluczowe jest zrozumienie różnic między mutowalnymi a niemutowalnymi. Zrozumienie tych cech pomaga unikać niezamierzonych zachowań w Twoim kodzie oraz pisać bardziej solidne i czytelne programy.
Możesz śledzić ten artykuł, korzystając z Visual Studio Code na naszym kanale YouTube. Proszę również sprawdzić nasz kanał YouTube.