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.”
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
city = "Warsaw"
print(city)
Części tej linii:
city— nazwa (zmienna);=jest operatorem przypisania: „niech nazwa po lewej wskaże czyli po prawej stronie”"Warsaw"— wartość (obiekt).
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 = 100
best_score = score
print(score)
print(best_score)
Tutaj dwa imiona — score oraz
best_score — ale jeden obiekt, na który oboje
wskazują:
Przeniesienie nie zmienia starej nazwy
Kontynuujmy ten sam przykład:
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:
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:
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:
Obiekt 100 stał się nieosiągalne (unreachable) —
nie można do niego „dotrzeć”
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.
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:
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:
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.
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ę):
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:
print(favourite_city)
favourite_city = "Warsaw"
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.