Jak wydrukować wyjątek w Pythonie?

Odpowiedzi:

1061

W przypadku Python 2.6 i nowszych oraz Python 3.x:

except Exception as e: print(e)

W przypadku Python 2.5 i wcześniejszych użyj:

except Exception,e: print str(e)
Jldupont
źródło
41
str( KeyError('bad'))=> 'bad'- nie określa typu wyjątku
Dave
10
print (e) na kluczach wydaje się dawać tylko klucz, ale nie pełny komunikat wyjątku, który jest mniej niż pomocny.
Veggiet
14
Jeśli zamierzasz wydrukować wyjątek, lepiej użyć print(repr(e)); podstawowa Exception.__str__implementacja zwraca tylko komunikat wyjątku, a nie typ. Lub użyj tracebackmodułu, który ma metody drukowania bieżącego wyjątku, sformatowanego lub pełnego śledzenia.
Martijn Pieters
450

tracebackModuł dostarcza sposoby formatowania i drukowania wyjątki i ich tracebacks np byłoby wydrukować wyjątek jak domyślny handler robi:

import traceback

try:
    1/0
except Exception:
    traceback.print_exc()

Wynik:

Traceback (most recent call last):
  File "C:\scripts\divide_by_zero.py", line 4, in <module>
    1/0
ZeroDivisionError: division by zero
Cat Plus Plus
źródło
3
czy istnieje jakieś wywołanie get_error_message, które mogę wydrukować, widząc, ponieważ używam własnej procedury drukowania do dodawania innych rzeczy.
MikeSchem
10
@MikeSchem error_message = traceback.format_exc()
heyzling
3
Dziękuję, tego chciałem. Cały ślad, nie tylko rodzaj błędu i komunikat
Ken Bellows,
Ten wycięty nie używa przechwyconego obiektu wyjątku. Czy możesz rozwinąć kod, aby używał „ex”? - jak w except Exception as ex:...
aaronsteers
@aaronsteers wykorzystuje przechwycony wyjątek; w module obsługi wyjątków bieżący wyjątek jest dostępny za pośrednictwem sys.exc_info()funkcji i traceback.print_exc()funkcja pobiera go stamtąd. Zawsze będziesz musiał podać wyjątek tylko jawnie, gdy nie obsługujesz wyjątku lub gdy chcesz wyświetlić informacje na podstawie innego wyjątku.
Martijn Pieters
169

W Pythonie 2.6 lub nowszym jest nieco czystszy:

except Exception as e: print(e)

W starszych wersjach jest nadal dość czytelny:

except Exception, e: print e
ilya n.
źródło
15
W python3, musisz użyć pierwszego sposobu, z „as”.
Sam Watkins,
53

Jeśli chcesz przekazać ciągi błędów, oto przykład z błędów i wyjątków (Python 2.6)

>>> try:
...    raise Exception('spam', 'eggs')
... except Exception as inst:
...    print type(inst)     # the exception instance
...    print inst.args      # arguments stored in .args
...    print inst           # __str__ allows args to printed directly
...    x, y = inst          # __getitem__ allows args to be unpacked directly
...    print 'x =', x
...    print 'y =', y
...
<type 'exceptions.Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs
Nick Dandoulakis
źródło
38

(Chciałem zostawić to jako komentarz do odpowiedzi @ jldupont, ale nie mam wystarczającej reputacji).

Odpowiedzi takie jak @ jldupont widziałem także w innych miejscach. FWIW, myślę, że należy zauważyć, że to:

except Exception as e:
    print(e)

sys.stdoutdomyślnie wypisze wyjście błędu . Bardziej odpowiednie podejście do obsługi błędów ogólnie byłoby:

except Exception as e:
    print(e, file=sys.stderr)

(Pamiętaj, że musisz to zrobić, aby import systo zadziałało). W ten sposób błąd jest wypisywany STDERRzamiast STDOUT, co pozwala na poprawne parsowanie / przekierowanie / etc. Rozumiem, że pytanie dotyczyło wyłącznie „drukowania błędu”, ale wydaje się ważne, aby wskazać tutaj najlepszą praktykę, zamiast pomijać ten szczegół, który może prowadzić do niestandardowego kodu dla każdego, kto ostatecznie nie uczy się lepiej.

Nie użyłem tego tracebackmodułu, jak w odpowiedzi Cat Plus Plus, i może to najlepszy sposób, ale pomyślałem, że go tam wyrzucę.

grish
źródło
1
Sugerowałbym dalsze dodanie koloru = True. Zauważyłem, że dzięki systemd (i nie używaniu odpowiedniego frameworka rejestrowania) buforowanie podczas przechwytywania do dziennika nie jest tym, czego bym się spodziewał.
Cameron Kerr
20

Python 3: logging

Zamiast korzystać z print()funkcji podstawowej , loggingmożna użyć bardziej elastycznego modułu do zarejestrowania wyjątku. Do loggingoferty Moduł wiele dodatkowych funkcjonalności, np logu do danego pliku dziennika rejestrowania komunikatów ze znaczników czasu i dodatkowych informacji o tym, gdzie rejestrowanie się. (Aby uzyskać więcej informacji, sprawdź oficjalną dokumentację .)

Rejestrowanie wyjątku można wykonać za pomocą funkcji na poziomie modułu w następujący logging.exception()sposób:

import logging

try:
    1/0
except BaseException:
    logging.exception("An exception was thrown!")

Wynik:

ERROR:root:An exception was thrown!
Traceback (most recent call last):
  File ".../Desktop/test.py", line 4, in <module>
    1/0
ZeroDivisionError: division by zero 

Uwagi:

  • funkcja logging.exception()powinna być wywoływana tylko z modułu obsługi wyjątków

  • loggingmoduł nie powinien być stosowany wewnątrz uchwytu, aby uniknąć rejestrowania RecursionError(dzięki @PrakharPandey)


Alternatywne poziomy dziennika

Możliwe jest także zarejestrowanie wyjątku na innym poziomie dziennika przy użyciu argumentu słowa kluczowego w następujący exc_info=Truesposób:

logging.debug("An exception was thrown!", exc_info=True)
logging.info("An exception was thrown!", exc_info=True)
logging.warning("An exception was thrown!", exc_info=True)
winklerrr
źródło
1
Nie należy go używać w
module
4

Podnoszenie jednego błędu liniowego można wykonać za pomocą instrukcji aser, jeśli to właśnie chcesz zrobić. Pomoże to w pisaniu statycznie naprawialnego kodu i wczesnym sprawdzaniu błędów.

assert type(A) is type(""), "requires a string"
whatnick
źródło
2

Można w zasadzie kontrolować, które informacje ze śledzenia mają być wyświetlane / rejestrowane podczas przechwytywania wyjątków.

Kod

with open("not_existing_file.txt", 'r') as text:
    pass

wygeneruje następujący ślad:

Traceback (most recent call last):
  File "exception_checks.py", line 19, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Wydrukuj / zaloguj pełny ślad

Jak już wspomniano inni, możesz złapać cały traceback za pomocą modułu traceback:

import traceback
try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    traceback.print_exc()

Spowoduje to wygenerowanie następującego wyniku:

Traceback (most recent call last):
  File "exception_checks.py", line 19, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Możesz to zrobić, używając rejestrowania:

try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    logger.error(exception, exc_info=True)

Wynik:

__main__: 2020-05-27 12:10:47-ERROR- [Errno 2] No such file or directory: 'not_existing_file.txt'
Traceback (most recent call last):
  File "exception_checks.py", line 27, in <module>
    with open("not_existing_file.txt", 'r') as text:
FileNotFoundError: [Errno 2] No such file or directory: 'not_existing_file.txt'

Drukuj / loguj tylko nazwę błędu / komunikat

Możesz nie być zainteresowany całym procesem śledzenia, ale tylko najważniejszymi informacjami, takimi jak nazwa wyjątku i komunikat wyjątku, użyj:

try:
    with open("not_existing_file.txt", 'r') as text:
        pass
except Exception as exception:
    print("Exception: {}".format(type(exception).__name__))
    print("Exception message: {}".format(exception))

Wynik:

Exception: FileNotFoundError
Exception message: [Errno 2] No such file or directory: 'not_existing_file.txt'
Gin z tonikiem
źródło