Zanurkuj w Pythonie/Obiekty i klasy: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Piotr (dyskusja | edycje)
Piotr (dyskusja | edycje)
Linia 270:
W Pythonie, aby utworzyć instancję pewnej klasy, wywołujemy klasę, jakby to była zwykła funkcja zwracająca pewną wartość. Python nie posiada jakiegoś kluczowego słowa jakim jest np. operator <tt>new</tt> w Javie czy C++.
}}
 
=== Odśmiecanie pamięci ===
 
Jeśli tworzenie nowej instancji jest proste, to usuwanie jej jest jeszcze prostrze. W ogólności nie musimy wyraźnie zwalniać instancje klasy, ponieważ Python zwalnie je automatycznie, gdy wychodzą one poza swój zasięg. W Pythonie rzadko występują wycieki pamięci.
==== Przykład 5.8. Próba zaimpelemtowania wycieku pamięci ====
 
>>> def leakmem():
... f = fileinfo.FileInfo('/music/_singles/kairo.mp3') #(1)
...
>>> for i in range(100):
... leakmem() #(2)
 
# Za każdym razem, gdy funkcja <tt>leakmem</tt> jest wywoływana, zostaje utworzona instancja klasy <tt>FileInfo</tt> przypisana do zmiennej <tt>f</tt>, która jest lokalną zmienną wewnątrz funkcji. Wtedy funkcja kończy się bez jakiegokolwiek zwolnienia zmiennej <tt>f</tt>, a więc spodziewalibyśmy się wycieku pamięci, lecz tak nie będzie. Kiedy funkcja się kończy, lokalna zmienna <tt>f</tt> wychodzi poza swój zakres. W tym miejscu nie ma więcej żadnych referencji do nowej instancji <tt>FileInfo</tt>, ponieważ nigdzie nie przypisywaliśmy jej do czegoś innego niż <tt>f</tt>), tak więc Python zniszczy instancję za nas.
# Nie zależnie od tego, jak wiele razy wywołamy funkcję <tt>leakmem</tt>, nigdy nie otrzymamy wycieku pamięci, ponieważ za każdym razem kiedy to zrobimy Python będzie niszczył nowo utworzony obiekt przed wyjściem z funkcji <tt>leakmem</tt>.
 
Technicznym terminem tego sposobu odśmiecania pamięci jest „zliczanie odwołań”. Python przechowuje listę referencji do każdej utworzonej instancji. W powyższym przykładzie, mamy tylko jedną referencję do instancji <tt>FileInfo</tt> -- zmienną <tt>f</tt>. Kiedy funkcja się kończy, zmienna <tt>f</tt> wychodzi poza zakres, więc licznik odwołań zmiejsza się do <tt>0</tt> i Python niszczy tę instancję automatycznie.
 
W poprzednich wersjach Pythona występowały sytuacje, gdy zliczanie odwołań zawodziało i Python nie mógł wyczyścić po nas pamięci. Jeśli tworzyłeś dwie instancję, które odowoływały się do siebie nawzajem (np. instancja listy dwukierunkowej (ang. double linked list), w których każdy węzeł wskazuje na poprzedni i następny znajdujący się w liście), żadna instancja nie była niszczona automatycznie, ponieważ Python uważał (poprawnie), że ciągle mamy referencję do każdej instancji. Od Pythonie 2.0 mamy dodatkowy sposób odśmiecania pamięci nazywany po ang. “mark-and-sweep” (znacz i zamiataj), dzięki któremu w sprytny sposób Python odnajduje różne wirtualne blokady i poprawnie czyści referencje tworzące cykl.
 
Podsumowywując w języku tym można po prostu zapomnieć o zarządzaniu pamięcią i pozostawić tę sprawę Pythonowi.
 
== Exploring UserDict: A Wrapper Class ==