Zmienialne i niezmienialne w Pythonie

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.

YouTube Video