2013-03-25 14 views
31

Podczas debugowania kodu Pythona w interaktywnym monicie (REPL), często napiszę kod, który podnosi wyjątek, ale nie zapakowałem go w try/except, więc gdy błąd zostanie podniesiony, mam na zawsze utracił obiekt wyjątku.Jak uzyskać ostatni obiekt wyjątku po zgłoszeniu błędu w pytaniu Python?

Często komunikat traceback i komunikat o błędzie Python nie wystarcza. Na przykład podczas pobierania adresu URL serwer może zwrócić błąd 40x i potrzebujesz treści odpowiedzi przez error.read() ... ale nie masz już obiektu błędu. Na przykład:

>>> import urllib2 
>>> f = urllib2.urlopen('http://example.com/api/?foo=bad-query-string') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    ... 
urllib2.HTTPError: HTTP Error 400: Bad Request 

Drat, co mówi ciało odpowiedzi? Prawdopodobnie zawierał cenne informacje o błędzie ...

Zdaję sobie sprawę, że zwykle łatwo jest ponownie uruchomić kod zawinięty w try/except, ale to nie jest idealne. Zdaję sobie również sprawę, że w tym konkretnym przypadku, gdybym używał biblioteki requests (która nie podnosi błędów HTTP), nie miałbym tego problemu ... ale naprawdę zastanawiam się, czy istnieje bardziej ogólny sposób ostatni obiekt wyjątku w pytaniu Python w tych przypadkach.

Odpowiedz

44

Moduł sys udostępnia niektóre funkcje do badania wyjątków: post-hoc: sys.last_type, sys.last_value i sys.last_traceback.

sys.last_value to produkt, którego szukasz.

+1

Bardzo ładny, dziękuję! Działa jak udokumentowane. Dziwne, że moje poszukiwania Google nie znalazły tego, ale no cóż. (Pomimo bycia dość wytrawnym programistą Pythona, codziennie uczę się czegoś o Pythonie lub jego standardowych bibliotekach ...) –

+0

@BenHoyt FYI, zgodnie z dokumentacją 'sys'," Te trzy są dostępne tylko w sesji interaktywnej po traceback został wydrukowany. ". – satoru

+1

@satoru Cóż, oczywiście. W normalnym programie nieobsługiwany wyjątek zakończy program. – Cairnarvon

4

Jak wspomniałem @Cairnarvon, nie znalazłem żadnego członka last_value, który jest modułem sys.

sys.exc_info() załatwiłem sprawę. sys.exc_info() zwraca krotkę z trzema wartościami (type, value, traceback).

Tak sys.exc_info()[1] da czytelny błąd. Oto przykład,

import sys 
list = [1,2,3,4] 
try: 
    del list[8] 
except Exception: 
    print(sys.exc_info()[1]) 

wyjście wola list assignment index out of range

Również traceback.format_exc() z modułem traceback mogą być wykorzystane do wydrukowania podobnych informacji.

Poniżej jest wyjście jeśli jest stosowany fortmat_exec(),

Traceback (most recent call last): File "python", line 6, in <module> IndexError: list assignment index out of range

Powiązane problemy