Zachowanie jest nie dobrze udokumentowane i jest obecny we wszystkich wersjach Pythonie 1,5-dosyć aż Python 3.4:
W ramach tej zmiany globalne modułu nie są już na siłę ustawiona do None
podczas zamykania interpretera w większości przypadków, zamiast polegać na normalnej pracy cyklicznego odśmiecacza.
Jedyna dokumentacja dla zachowania jest moduleobject.c
source code:
/* To make the execution order of destructors for global
objects a bit more predictable, we first zap all objects
whose name starts with a single underscore, before we clear
the entire dictionary. We zap them by replacing them with
None, rather than deleting them from the dictionary, to
avoid rehashing the dictionary (to some extent). */
Należy pamiętać, że ustawienie wartości None
jest optymalizacja; Alternatywą byłoby usunięcie nazw z mapowania, które prowadziłyby do różnych błędów (wyjątków, a nie AttributeError
s przy próbie użycia globali z obsługi __del__
).
Jak dowiedziałeś się na liście mailingowej, zachowanie poprzedza cykliczny garbage collector; był to added in 1998, natomiast cyklicznym śmieciarzem był added in 2000. Ponieważ obiekty funkcyjne zawsze odwołują się do modułu, wszystkie obiekty funkcyjne w module dotyczą odwołań kołowych, dlatego konieczne było wyczyszczenie przed wprowadzeniem GC.
Został zachowany na miejscu nawet po dodaniu cyklicznego GC, ponieważ mogą występować obiekty o metodach związanych z cyklami. Te aren't otherwise garbage-collectable i czyszczenie słownika modułów spowodowałyby przynajmniej usunięcie modułu z takich cykli. W przeciwnym razie wszystkie globale tego modułu będą żyły.
Zmiany wprowadzone do PEP 442 zrobić teraz to możliwe dla śmieciarza, aby usunąć odwołania cykliczne z obiektami, które zapewniają __del__
finalizatora, eliminując potrzebę, aby wyczyścić moduł __dict__
dla większości przypadków. Kod to still there, ale jest on wyzwalany tylko wtedy, gdy atrybut __dict__
jest wciąż aktywny, nawet po przeniesieniu zawartości sys.modules
do słabych odniesień i uruchomieniu kolekcji GC podczas zamykania interpretera; moduł finalizatora modułów po prostu zmniejsza ich liczbę referencyjną.