Python 3 (aktualizacja do oryginalnego odpowiedź):
W Pythonie 3, rada cytowane w pytaniu została usunięta z dokumentacją Pythona. Moja oryginalna odpowiedź (poniżej) dotyczy tylko wersji Pythona zawierających cytat z ich dokumentacji.
Python 2:
Python garbage collector będzie w końcu znaleźć i usunąć koliste referencje, jak ten stworzony przez odniesienie do stosu Traceback od wewnątrz jednego stosu ramki siebie, więc nie idź wróć i przepisz swój kod. Ale idąc dalej, można stosować się do zaleceń
http://docs.python.org/library/sys.html
(gdzie udokumentowano exc_info()
) i powiedzieć:
exctype, value = sys.exc_info()[:2]
gdy trzeba chwycić wyjątek.
Dwa kolejne myśli:
Po pierwsze, dlaczego uciekasz exc_info()
w ogóle?
Jeśli chcesz złapać wyjątek nie powinien po prostu powiedzieć:
try:
...
except Exception as e: # or "Exception, e" in old Pythons
... do with with e ...
zamiast mucking z obiektami wewnątrz modułu sys
?
Po drugie: Dobra, dałem wiele rad, ale tak naprawdę nie odpowiedziałem na twoje pytanie.:-)
Dlaczego tworzony jest cykl? Cóż, w prostych przypadkach, cykl jest tworzony, gdy obiekt odnosi się do siebie:
a = [1,2,3]
a.append(a)
Albo gdy dwa obiekty odnoszą się do siebie nawzajem:
a = [1,2,3]
b = [4,5,a]
a.append(b)
W obu tych przypadkach, gdy końce funkcyjnych wartości zmiennych będą nadal istnieć, ponieważ są zablokowane w uścisku z odniesieniem: żadne nie może zniknąć, dopóki drugie nie zniknie! Tylko nowoczesny garbage Python może rozwiązać ten problem, zauważając w końcu pętlę i ją łamiąc.
Tak więc kluczem do zrozumienia tej sytuacji jest obiekt "traceback" - trzecia rzecz zwrócona przez exc_info()
- zawiera "ramkę stosu" dla każdej funkcji, która była aktywna po wywołaniu wyjątku . I te ramki stosów są "martwymi" obiektami pokazującymi, co jest prawdziwe, gdy wywołano execption; ramy są wciąż żywe! Funkcja, która wychwyciła wyjątek, wciąż jest żywa, więc jego ramka stosu jest żywą istotą, wciąż rosnącą i tracącą zmienne odniesienia, ponieważ jej kod jest wykonywany w celu obsługi wyjątku (i robienia wszystkiego, co robi, gdy kończy się klauzula "wyjątkiem" i przechodzi o swojej pracy).
Kiedy więc powiemy t = sys.exc_info()[2]
, jedna z tych ramek wewnątrz traceback - w rzeczywistości rama należąca do aktualnie działającej funkcji - teraz ma zmienną o nazwie t
, która wskazuje na ramkę stosu samodzielnie, tworząc pętlę, podobnie jak te, które pokazałem powyżej.
[Ostrzeżenie] (https://docs.python.org/3.2/library/sys.html#sys.exc_info), o którym wspomniałeś, używając porady "[: 2]", zostało usunięte z dokumentów, ponieważ Python 3.3. Powody są wyjaśnione w [# 7340] (https://bugs.python.org/issue7340). Sztuczka '[: 2]' już nie działa, atrybut '__traceback__' obsługiwanego wyjątku powinien być zamiast tego ustawiony na' Brak'. Pokrewne PEP: [344] (https://www.python.org/dev/peps/pep-0344/#open-issue-garbage-collection), [3134] (https://www.python.org/dev/peps/pep-3134/# open-issue-garbage-collection), [3110] (https://www.python.org/dev/peps/pep-3110/#semantic-changes). – Delgan