如何在Python中打印异常?

TIM*_*MEX 609 python error-handling exception

try:
    something here
except:
    print('the whatever error occurred.')
Run Code Online (Sandbox Code Playgroud)

如何在except:块中打印错误/异常?

jld*_*ont 898

对于Python 2.6及更高版本和Python 3.x:

except Exception as e: print(e)
Run Code Online (Sandbox Code Playgroud)

对于Python 2.5及更早版本,请使用:

except Exception,e: print str(e)
Run Code Online (Sandbox Code Playgroud)

  • `str(KeyError('bad'))`=>`'bad'` - 不告诉异常类型 (26认同)
  • 对keyerrors的print(e)似乎只给出了密钥,但没有给出完整的异常消息,这没有什么用。 (6认同)
  • @MartijnPieters `print(repr(e))` 没有给出任何 stracktrace。来自回溯模块的“print_exc”*(在另一个答案中提到)*尽管在这种情况下有效。 (3认同)
  • @MartijnPieters虽然你没有,但你确实建议专门使用 `print(repr(e))` ,而关于回溯,你给出了一些通用声明,它有多种方法来打印异常。这听起来像是您更喜欢“repr()”方式,并且由于您的评论得到了如此多的支持,我认为值得写一个可见的回复来说明那里存在什么更好的方法。 (3认同)
  • 如果要打印异常,最好使用`print(repr(e))`; 基本的Exception .__ str__实现仅返回异常消息,而不返回类型。或者,使用`traceback`模块,该模块具有打印当前异常,格式化或完整追溯的方法。 (2认同)
  • @Hi-Angel:我在哪里声称打印 `repr(e)` 会给出堆栈跟踪?我正在讨论 `str(e)` 和 `repr(e)` 之间的区别,后者包含更多信息,您也可以在回溯的最后一行中看到这些信息。我在评论中明确提到了“traceback”模块。 (2认同)
  • @Hi-Angel 我专注于打印_just_异常,并且回溯模块也具有仅专注于异常的功能。 (2认同)

Cat*_*lus 387

traceback模块提供了格式化和打印异常及其回溯的方法,例如,这将打印异常,就像默认处理程序一样:

import traceback

try:
    1/0
except Exception:
    traceback.print_exc()
Run Code Online (Sandbox Code Playgroud)

输出:

Traceback (most recent call last):
  File "C:\scripts\divide_by_zero.py", line 4, in <module>
    1/0
ZeroDivisionError: division by zero
Run Code Online (Sandbox Code Playgroud)

  • @aaronsteers 它确实使用了捕获的异常;在异常处理程序中,当前异常可通过“sys.exc_info()”函数获得,并且“traceback.print_exc()”函数从那里获取它。仅当不处理异常或要显示基于不同异常的信息时,才需要显式传入异常。 (7认同)
  • 是的,有时我想保留异常并稍后打印它,当我不再处于“例外”块时。 (6认同)
  • @MikeSchem```error_message = traceback.format_exc()`'' (5认同)
  • 此片段不使用捕获的异常对象。您可以扩展代码以使用“ex”吗?- 如“例外情况如前:”... (3认同)
  • 我使用自己的打印例程添加其他内容时,是否可以打印某种get_error_message调用。 (2认同)

ily*_* n. 165

Python 2.6或更高版本中,它更清晰:

except Exception as e: print(e)
Run Code Online (Sandbox Code Playgroud)

在旧版本中,它仍然具有可读性:

except Exception, e: print e
Run Code Online (Sandbox Code Playgroud)

  • 在python3中,必须使用第一种方式,使用"as". (15认同)

Nic*_*kis 49

如果你想传递错误字符串,这里是一个错误和异常的例子(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
Run Code Online (Sandbox Code Playgroud)


win*_*rrr 47

蟒蛇3: logging

代替使用基本print()功能,logging可以使用更灵活的模块来记录异常。该logging模块提供了许多额外的功能,例如将消息记录到给定的日志文件中,记录带有时间戳的消息以及有关记录发生位置的附加信息。(有关更多信息,请查看官方文档。)

可以使用模块级函数来记录异常,logging.exception()如下所示:

import logging

try:
    1/0
except BaseException:
    logging.exception("An exception was thrown!")
Run Code Online (Sandbox Code Playgroud)

输出:

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 
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 该函数logging.exception()只能从异常处理程序中调用

  • logging模块不应在日志记录处理程序中使用以避免RecursionError(感谢@PrakharPandey)


替代日志级别

也可以使用关键字参数来记录另一个日志级别的异常,exc_info=True如下所示:

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)
Run Code Online (Sandbox Code Playgroud)

  • 不应在日志记录处理程序中使用以避免 RecursionError (2认同)

Gin*_*nic 40

在捕获异常时,可以很好地控制要显示/记录回溯中的哪些信息。

编码

with open("not_existing_file.txt", 'r') as text:
    pass
Run Code Online (Sandbox Code Playgroud)

将产生以下回溯:

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'
Run Code Online (Sandbox Code Playgroud)

打印/记录完整的回溯

正如其他人已经提到的,您可以使用回溯模块捕获整个回溯:

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

这将产生以下输出:

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'
Run Code Online (Sandbox Code Playgroud)

您可以通过使用日志记录来实现相同的目的:

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

输出:

__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'
Run Code Online (Sandbox Code Playgroud)

仅打印/记录错误名称/消息

您可能对整个回溯不感兴趣,而只对最重要的信息(例如异常名称和异常消息)感兴趣,请使用:

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))
Run Code Online (Sandbox Code Playgroud)

输出:

Exception: FileNotFoundError
Exception message: [Errno 2] No such file or directory: 'not_existing_file.txt'
Run Code Online (Sandbox Code Playgroud)

  • 希望我可以多次投票赞成这个答案,因为它比已接受的答案更有帮助。 (6认同)

小智 37

尝试这个

try:
    print("Hare Krishna!")
except Exception as er:
    print(er)
Run Code Online (Sandbox Code Playgroud)

  • 通常没有解释的代码块并不是一个很好的答案。如果您能告诉我们为什么应该尝试此代码以及为什么它会/可能对操作有所帮助,这对社区会更有帮助。谢谢! (12认同)

gri*_*ish 36

(我打算将此作为对@ jldupont答案的评论,但我没有足够的声誉.)

我在其他地方也见过像@ jldupont这样的答案.FWIW,我认为重要的是要注意这一点:

except Exception as e:
    print(e)
Run Code Online (Sandbox Code Playgroud)

sys.stdout默认打印错误输出.一般来说,更合适的错误处理方法是:

except Exception as e:
    print(e, file=sys.stderr)
Run Code Online (Sandbox Code Playgroud)

(注意,你必须import sys为此工作.)这样,错误被打印STDERR而不是STDOUT,这允许正确的输出解析/重定向/等.我理解这个问题严格来说是"打印错误",但是在这里指出最佳实践似乎很重要,而不是忽略这些细节,这可能会导致任何最终没有学到更好的人的非标准代码.

我没有traceback在Cat Plus Plus的答案中使用该模块,也许这是最好的方式,但我想我会把它扔出去.

  • 我建议进一步添加flush=True。我已经注意到 systemd(并且没有使用适当的日志记录框架),捕获到日志时的缓冲不是我所期望的。 (2认同)

小智 8

在这里扩展“except Exception as e:”解决方案是一个不错的单行代码,其中包含一些附加信息,例如错误类型及其发生位置。


try:
    1/0
except Exception as e:
    print(f"{type(e).__name__} at line {e.__traceback__.tb_lineno} of {__file__}: {e}")
Run Code Online (Sandbox Code Playgroud)

输出:

ZeroDivisionError at line 48 of /Users/.../script.py: division by zero
Run Code Online (Sandbox Code Playgroud)

  • 最有用的答案。 (3认同)