Rozdział 3 · Twój pierwszy program w Python

Imiona i znaczenia

Poprawny model mentalny zmiennej w Python nie jest pudełkiem danych, lecz nazwą wskazującą na wartość.

Już stworzyliśmy imiona takie jak name w poprzednich sekcjach — Czas wyjaśnić, co to naprawdę oznacza.

Nie „pudełko z danymi”

Powszechna, choć nie do końca trafna metafora: „zmienna to pudełko, do którego wkłada się znaczenia.”

city 'Warsaw'
Nazwa wskazuje na znaczenie — a nie „zawiera”

Nazwa jest raczej strzałką wskazującą na wartość. Przypisanie city = "Warsaw" nie „wkłada” city — zmusza ono nazwę city wskazują na cechę łańcuch znaków "Warsaw"istnieje samodzielnie.

Tworzenie i czytanie imienia

names.py
city = "Warsaw"
print(city)

Części tej linii:

Wiele nazw — jeden obiekt

Ponieważ nazwa jest tylko wskaźnikiem, ten sam obiekt może mieć wiele imion jednocześnie. Weźmy przykład:

score.py
score = 100
best_score = score
print(score)
print(best_score)

Tutaj dwa imionascore oraz best_score — ale jeden obiekt, na który oboje wskazują:

scorebest_score100
Dwa odwołania do tego samego obiektu — a nie dwie osobne liczby 100
Częsty błąd myślowy
NIE MYŚL, że Python „skopiował 100 na dwie zmienne pudełkowe” link (reference): "nazwa jest związana z obiektem" zamiast "nazwa zawiera znaczenie".

Przeniesienie nie zmienia starej nazwy

Kontynuujmy ten sam przykład:

score2.py
score = 100
best_score = score
score = 120
print(score)       # 120
print(best_score)  # wciąż 100

String score = 120 jest ponowne przypisanie (rebinding): nazwa score zaczyna wskazywać na inny obiekt. Istniejący obiekt 100 jednocześnie nie zmienia się w żaden sposób — best_score nadal na to wskazuje:

score120best_score100
Po score = 120: Każda nazwa ma teraz własne, niezależne powiązanie

To ważna idea, do której będziemy wracać więcej niż raz, gdy mówimy o niezmienności liczb oraz strings (Rozdział 4), o listach i ich różnicach względem liczb, o tym, jak jeden i ten sam obiekt może być być dostępnym z wielu lokalizacji oraz w jaki sposób wartości są przekazywane do funkcji. Na razie Wystarczy pamiętać o samej zasadzie: zmiana zmienia relację z nazwą, nie obiekt.

Kiedy obiekt „znika”

Logiczne pytanie: jeśli score już nie wskazuje na 100, co się dzieje z samym obiektem 100? Kontynuujmy ten przykład o krok dalej:

score3.py
best_score = 130
print(score)       # 120
print(best_score)  # 130

Teraz nie ma score, ani best_score nie wskazywanie obiektu 100 — nie ma już żadnego połączenia:

score120best_score1301000 linków
100 stał się nieosiągalny — żadne imię już na niego nie wskazuje

Obiekt 100 stał się nieosiągalne (unreachable) — nie można do niego „dotrzeć”

To nieścisłe tak pisząc
„Gdy tylko zmienna przestaje wskazywać na wartość, garbage collector natychmiast usuwa tę wartość” best_score wskazywał na 100 nawet po score przypisany). Obiekt staje się kandydatem do usunięcia tylko wtedy, gdy żadnej nie utrzymuje z nim kontaktu.

Garbage collector: automatyczne zarządzanie pamięcią

Zazwyczaj nigdy nie będziesz musiał ręcznie „zwalniać” odśmiecacz (garbage collector) (garbage collector, GC) jest częścią samego Python, co automatycznie uwalnia pamięć od obiektów nieosiągalnych.

Wystarczy do codziennej pracy
Python śledzi obiekty i zwalnia pamięć, gdy obiekt nie może być już używany pod żadną nazwą w programie. Dlatego w Python (w przeciwieństwie do języków takich jak C) prawie nigdy nie piszesz kodu specjalnie po to, by zwolnić pamięć.

Co idzie głębiej: Liczenie linków

To opcjonalne, głębsze spojrzenie – możesz bezpiecznie pominąć go za pierwszym razem czytam i wracam później.

W CPython (implementacji Python, której używamy) każdy obiekt ma licznik: ile odniesień do niego istnieje teraz. Przejdźmy jeszcze raz przez nasz przykład, ale tym Kontrowersja:

Obiekt 100 — licznik referencji
score = 100          # объект 100: ссылок = 1
best_score = score   # объект 100: ссылок = 2
score = 120          # объект 100: ссылок = 1  (score теперь указывает на 120)
best_score = 130     # объект 100: ссылок = 0  (недостижим)

Dla zwykłych obiektów, nie wchodzących w cykliczne odniesienie w CPython moment, gdy licznik osiąga zero, zazwyczaj pokrywa się z momentem zwalniania pamięci — prawie od razu, bez opóźnienia. To wygodne, praktyczne zachowanie, ale nie gwarancja ustalona przez język Python jako całość — inne implementacje Python (na przykład PyPy)) zwalniają pamięć według innych zasad.

Liczenie ogniw ma jedną fundamentalną trudność — cykliczne linki:

Połączenie Kołowe (koncepcyjnie)
A ──→ B
↑      │
└──────┘

Wyobraź sobie dwa obiekty, każdy odnoszący się do drugiego. Nawet jeśli nie ma nazwy w Program już nie wskazuje na A ani B, nadal odnoszą się do siebie nawzajem — oraz liczba odniesień każdego z nich nie spada do zera. Dlatego w CPython, z wyjątkiem liczenia linki, jest osobna okrągły kontener śmieci, który okresowo szuka właśnie takich nieosiągalnych z zewnątrz cykli i je zwalnia.

Idźmy dalej, nie teraz
Celowo tu się zatrzymujemy. Do zarządzania pamięcią, czasu życia obiektu i modułu gc wrócimy do tego później w kursie, gdy pojawią się struktury danych, które naprawdę mogą tworzyć cykle (np. obiekty odwołujące się do siebie nawzajem). Na razie wystarczy wiedzieć, że taka sytuacja istnieje i Python ma mechanizm dla niej.

Mała notatka o del

Komenda del nie usuwa obiektu, lecz konkretną relację (Imię):

del_demo.py
x = 100
y = x
del x
print(y)  #100 – Obiekt wciąż zniknął

del x usuwa imię x przestrzeń nazw — ale NIE oznacza „usuń obiekt 100, bez względu na wszystko.” y nadal wskazuje na 100, Obiekt pozostaje w pełni dostępny przez y.

Przestrzeń nazw

Podczas działania programu Python przechowuje lista wszystkie utworzone nazwy oraz co każda z nich z nich teraz oznacza — to się nazywa przestrzeń nazw (namespace). Powyższe diagramy pokazują fragment takiej przestrzeni nazw w różnych momentach Wdrażanie programu.

Odnosi się do nazwy, która jeszcze nie została stworzona

Jeśli nazwa jest wspomniana przed jej utworzeniem w ramach cesji, Python nie może Zgadnij, o co chodzi — i zgłasza błąd:

broken.py
print(favourite_city)
favourite_city = "Warsaw"
Błąd
NameError: name 'favourite_city' is not defined

Więcej informacji o błędach i sposobie czytania takich komunikatów można znaleźć w sekcji 3.13.

Praktyka: Imiona i znaczenia
Interaktywny laptop bezpośrednio w przeglądarce – przypisuj, czytaj, NameError
Otwórz praktykę →