Отримання значення виключення в 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, принаймні відображатиме клас виключення. Я вважаю, що якщо ви роздруковуєте його, це для кінцевого користувача, який не байдуже, що це за клас, і просто хоче повідомлення про помилку.

Це дійсно залежить від винятку класу, з яким ви маєте справу, і від того, як він створений. Ви щось мали на увазі?


Я друкую це, щоб зробити звіт, str (e) добре, я здогадуюсь. Велике спасибі
Frias

8
Я вважаю за краще використовувати, e.messageтому args[0]що насправді це не може бути повідомленням.
cedbeu

3
repr (e) також корисний, якщо ви хочете отримати повний виняток (наприклад, NameError ("змінна глобальна назва" змінна "не визначена",), замість "глобальна назва" змінна "не визначена"
Бен Морріс,

49
ця відповідь небезпечний, так як він не в змозі за винятком Юникода , як це: raise Exception(u'jörn'). Невдача особливо погана, тому що ви ніколи не побачите фактичного винятку, а лише а UnicodeDecodeError. Якщо ви не знаєте кодування винятку (і більшу частину часу цього не робите), вам слід працювати repr(e)або якщо вам дійсно потрібно, скористайтеся іншим блоком для випробувань, крім вашого обліку виключень, який вловлює UnicodeDecodeErrors і повертається до repr(e).
Jörn Hees

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

2
ах, reprкорисно , спасибі, це , здається , що -то ще unicode, strщо кодує, ... може викликати виключення в залежності від вхідного сигналу. Не зовсім корисно при спробі зберегти виняток на вигляд, але передрук exception-safeздається
тире

2
Це набагато краще, ніж будь-які str()подібні рішення, оскільки воно фактично включає тип винятку. Коли str()я в 'status'той час, як repr()я отримав, KeyError('status')і я був як "аааааа, тепер я розумію помилку".
jlh

27

Хоча я усвідомлюю, що це давнє питання, я хотів би запропонувати використовувати tracebackмодуль для обробки результатів винятків.

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


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")'


0

Для python2, краще використовувати e.messageдля отримання повідомлення про виняток, це уникне можливого UnicodeDecodeError. Але так e.messageбуде порожнім для деяких винятків, наприклад OSError, у цьому випадку ми можемо додати exc_info=Trueдо нашої функції реєстрації даних, щоб не пропустити помилку.
Для python3 я думаю, що це безпечно у використанні str(e).


0

Якщо ви не знаєте тип / походження помилки, можете спробувати:

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

Але майте на увазі, ви отримаєте попередження pep8:

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

0

Щоб перевірити повідомлення про помилку і зробити щось із ним (з Python 3) ...

try:
    some_method()
except Exception as e:
    if {value} in e.args:
        {do something}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.