Uzyskiwanie wartości wyjątku w Pythonie


239

Jeśli mam ten kod:

try:
    some_method()
except Exception, e:

Jak mogę uzyskać tę wartość wyjątku (mam na myśli reprezentację ciągu)?

Odpowiedzi:


323

posługiwać się str

try:
    some_method()
except Exception as e:
    s = str(e)

Ponadto większość klas wyjątków będzie miała argsatrybut. Często pojawia args[0]się komunikat o błędzie.

Należy zauważyć, że samo użycie strzwróci pusty ciąg, jeśli nie ma komunikatu o błędzie, podczas gdy użycie reprzgodnie z zaleceniami pyfunc spowoduje przynajmniej wyświetlenie klasy wyjątku. Uważam, że jeśli drukujesz to, jest to dla użytkownika końcowego, który nie dba o to, czym jest klasa i chce tylko komunikat o błędzie.

To naprawdę zależy od klasy wyjątku, z którym mamy do czynienia, i od tego, w jaki sposób jest on tworzony. Czy miałeś na myśli coś konkretnego?


Piszę to, żeby zrobić raport, chyba, że ​​str (e) jest w porządku. Wielkie dzięki
Frias,

8
Wolałbym używać, e.messageponieważ args[0]może nie być tak naprawdę wiadomością.
cedbeu

3
repr (e) jest także pomocny, jeśli chcesz uzyskać pełny wyjątek (np. NameError („zmienna globalna nazwa” nie jest zdefiniowana ”,), zamiast„ globalna zmienna nazwa ”nie jest zdefiniowana”
Ben Morris

49
Ta odpowiedź jest niebezpieczne, ponieważ będzie to nie wyjątki unicode, takich jak ten: raise Exception(u'jörn'). Awaria jest szczególnie zła, ponieważ nigdy nie zobaczysz faktycznego wyjątku, ale tylko UnicodeDecodeError. Jeśli nie znasz kodowania wyjątku (a przez większość czasu tego nie wiesz), powinieneś albo pracować, repr(e)albo jeśli naprawdę potrzebujesz, użyj innego bloku try-wyjątku w obsłudze wyjątków, który przechwytuje błędy UnicodeDecodeErrors i wraca do repr(e).
Jörn Hees

11
Zgadzam się z @ JörnHees. Nie mogę policzyć, ile razy str(lub nawet unicodelub .format) spowodowało błędy z powodu obsługi Unicode. Jeśli nie masz pełnej kontroli nad treścią komunikatu o błędzie, ZAWSZE używaj, repraby uniknąć nieoczekiwanych błędów Unicode.
Kenny Trytek,

186

Użyj repr () i Różnica między użyciem repr i str

Używanie repr:

>>> try:
...     print(x)
... except Exception as e:
...     print(repr(e))
... 
NameError("name 'x' is not defined")

Używanie str:

>>> try:
...     print(x)
... except Exception as e:
...     print(str(e))
... 
name 'x' is not defined

2
ah, reprjest użyteczne dzięki, wydaje się cokolwiek innego unicode, strkodującego ... może podnieść wyjątek w zależności od wejścia. Nie całkiem przydatne, gdy staramy się zachować wyjątek, ale wygląda na to, exception-safeże wygląda na to
dashy

2
Jest to o wiele lepsze niż jakiekolwiek inne str()rozwiązanie, ponieważ w rzeczywistości zawiera typ wyjątku. Kiedy str()dostałem 'status', repr()dostałem KeyError('status')i byłem jak „aaaaah, teraz rozumiem błąd”.
jlh

27

Chociaż zdaję sobie sprawę, że to stare pytanie, chciałbym zasugerować użycie tracebackmodułu do obsługi danych wyjściowych wyjątków.

Służy traceback.print_exc()do drukowania bieżącego wyjątku do standardowego błędu, tak jak zostałby wydrukowany, gdyby nie został przechwycony, lub traceback.format_exc()do uzyskania takiego samego wyniku jak ciąg. Możesz przekazać różne argumenty do dowolnej z tych funkcji, jeśli chcesz ograniczyć wyjście lub przekierować drukowanie do obiektu podobnego do pliku.


23

Nie podano jeszcze innego sposobu:

try:
    1/0
except Exception, e:
    print e.message

Wynik:

integer division or modulo by zero

args[0] może nie być wiadomością.

str(e)może zwrócić ciąg z otaczającymi go cudzysłowami i być może z wiodącym, ujeśli unicode:

'integer division or modulo by zero'

repr(e) daje pełną reprezentację wyjątku, która prawdopodobnie nie jest tym, czego chcesz:

"ZeroDivisionError('integer division or modulo by zero',)"

edytować

Mój błąd !!! Wygląda na to żeBaseException.message został wycofany2.6 , a ostatecznie zdecydowanie wydaje się, że nadal nie ma standardowego sposobu wyświetlania komunikatów o wyjątkach. Sądzę więc, że najlepiej jest zająć się twoimi potrzebami e.argsi str(e)zależnie od nich (i być może e.messagejeśli używana biblioteka bazuje na tym mechanizmie).

Na przykład z pygraphviz , e.messagejest to jedyny sposób, aby wyświetlać prawidłowo wyjątku, stosując str(e)otoczą wiadomość z u''.

Ale MySQLdbwłaściwym sposobem na odzyskanie wiadomości jest e.args[1]: e.messagejest pusta i str(e)wyświetli się'(ERR_CODE, "ERR_MSG")'


0

W przypadku python2 lepiej jest użyć, e.messageaby uzyskać komunikat wyjątku, pozwoli to uniknąć możliwego UnicodeDecodeError. Ale tak e.messagebędzie puste dla niektórych wyjątków, takich jak OSError, w którym to przypadku możemy dodać exc_info=Truedo naszej funkcji logowania, aby nie przegapić błędu.
W przypadku python3 myślę, że można go bezpiecznie używać str(e).


0

Jeśli nie znasz typu / źródła błędu, możesz spróbować:

import sys
try:
    doSomethingWrongHere()
except:
    print('Error: {}'.format(sys.exc_info()[0]))

Ale pamiętaj, otrzymasz ostrzeżenie pep8:

[W] PEP 8 (E722): do not use bare except

0

Aby sprawdzić komunikat o błędzie i coś z nim zrobić (w Pythonie 3) ...

try:
    some_method()
except Exception as e:
    if {value} in e.args:
        {do something}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.