Получение значения исключения в Python

239

Если у меня есть этот код:

try:
    some_method()
except Exception, e:

Как я могу получить это значение исключения (я имею в виду строковое представление)?

Фриас
источник

Ответы:

323

использование str

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

Кроме того, большинство классов исключений будет иметь argsатрибут. Часто args[0]будет сообщение об ошибке.

Следует отметить, что простое использование strвернет пустую строку, если нет сообщения об ошибке, тогда как использование reprкак рекомендует pyfunc по крайней мере отобразит класс исключения. Я предполагаю, что если вы распечатываете это, это для конечного пользователя, который не заботится о том, что класс и просто хочет сообщение об ошибке.

Это действительно зависит от класса исключения, с которым вы имеете дело, и от того, как он создан. Вы имели в виду что-то особенное?

aaronasterling
источник
Я печатаю это, чтобы сделать отчет, я думаю, что str (e) в порядке. Большое спасибо
Frias
8
Я бы предпочел использовать, e.messageпотому args[0]что на самом деле не может быть сообщение.
cedbeu
3
Функция repr (e) также полезна, если вы хотите получить полное исключение (например, NameError («глобальное имя« переменная »не определена»,) вместо «глобального имени» переменная «не определена»
Бен Моррис,
49
этот ответ опасен, так как он не в состоянии за исключением Юникода , как это: raise Exception(u'jörn'). Отказ особенно плох, потому что вы никогда не увидите фактическое исключение, а просто UnicodeDecodeError. Если вы не знаете кодировку исключения (и большую часть времени этого не знаете), вам следует либо продолжить работу, repr(e)либо, если вам действительно нужно, использовать другой блок try-exc в вашей обработке исключений, который перехватывает UnicodeDecodeErrors и возвращается к repr(e),
Йорн Хис
11
Согласитесь с @ JörnHees. Я не могу сосчитать, сколько раз str(или даже unicodeили .format) вызывал ошибки из-за обработки Unicode. Если у вас нет полного контроля над содержимым сообщения об ошибке, ВСЕГДА используйте, reprчтобы избежать непредвиденных ошибок Unicode.
Кенни Трайтек,
186

Используйте repr () и разницу между использованием repr и str

Использование repr:

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

Использование str:

>>> try:
...     print(x)
... except Exception as e:
...     print(str(e))
... 
name 'x' is not defined
pyfunc
источник
2
ах, reprполезно , спасибо, это , кажется , что -то еще unicode, strкодирующим, ... может вызвать исключение в зависимости от входного сигнала. Не совсем полезно при попытке сохранить исключение для просмотра, но, exception-safeкажется , repr
dashesy
2
Это намного лучше, чем любые str()подобные решения, потому что оно фактически включает тип исключения. Когда str()я получил 'status'время, repr()я получил, KeyError('status')и я был как «аааааа, теперь я понимаю ошибку».
JLH
27

Хотя я понимаю, что это старый вопрос, я хотел бы предложить использовать tracebackмодуль для обработки вывода исключений.

Используется traceback.print_exc()для печати текущего исключения со стандартной ошибкой, точно так же, как оно будет напечатано, если оно останется необработанным, или traceback.format_exc()для получения того же вывода, что и строка. Вы можете передавать различные аргументы любой из этих функций, если хотите ограничить вывод или перенаправить печать в файлоподобный объект.

Blckknght
источник
23

Другой путь еще не был дан:

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

Вывод:

integer division or modulo by zero

args[0] может на самом деле не быть сообщением.

str(e)может вернуть строку с окружающими кавычками и, возможно, с ведущими, uесли Unicode:

'integer division or modulo by zero'

repr(e) дает полное представление исключения, которое, вероятно, не то, что вы хотите:

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

редактировать

Виноват !!! Кажется, что BaseException.message это устарело2.6 , наконец, определенно кажется, что до сих пор нет стандартизированного способа отображения сообщений об исключениях. Поэтому я думаю, что лучше всего справиться с вашими потребностями e.argsи в str(e)зависимости от них (и, возможно, e.messageесли используемая вами библиотека полагается на этот механизм).

Например, с pygraphviz, e.messageэто единственный способ правильно отобразить исключение, используя str(e)будет окружать сообщение с u''.

Но с MySQLdb, правильный способ получить сообщение e.args[1]: e.messageпусто, и str(e)будет отображаться'(ERR_CODE, "ERR_MSG")'

cedbeu
источник
0

Для python2 лучше использовать, e.messageчтобы получить сообщение об исключении, этого можно избежать UnicodeDecodeError. Но yes e.messageбудет пустым для каких-то исключений, например OSError, в этом случае мы можем добавить exc_info=Trueк нашей функции регистрации, чтобы не пропустить ошибку.
Я думаю, что для python3 это безопасно str(e).

apporc
источник
0

Если вы не знаете тип / происхождение ошибки, вы можете попробовать:

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

Но имейте в виду, вы получите предупреждение pep8:

[W] PEP 8 (E722): do not use bare except
Kostanos
источник
0

Чтобы просмотреть сообщение об ошибке и что-то с ним сделать (с Python 3) ...

try:
    some_method()
except Exception as e:
    if {value} in e.args:
        {do something}
DanGoodrick
источник