如何在 Python 中打印异常?

How do I print an exception in Python?

提问人:TIMEX 提问时间:9/27/2009 最后编辑:Mateen UlhaqTIMEX 更新时间:2/10/2023 访问量:1936202

问:

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

try:
    ...
except:
    print(exception)
Python 异常 错误处理

评论

4赞 Stevoisiak 9/20/2018
相关新闻: 如何在不停止程序的情况下打印完整的回溯?
0赞 Pythoneer 1/7/2023
这回答了你的问题吗?如何在不停止/退出程序的情况下捕获和打印完整的异常回溯?

答:

70赞 Nick Dandoulakis 9/27/2009 #1

如果您想传递错误字符串,以下是错误和异常 (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
1901赞 jldupont 9/27/2009 #2

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

except Exception as e: print(e)

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

except Exception,e: print str(e)

评论

111赞 Dave 8/29/2015
str( KeyError('bad')) => 'bad'-- 不告诉异常类型
44赞 Veggiet 2/10/2019
keyerrors 上的 print(e) 似乎只给出了键,但没有给出完整的异常消息,这没什么用。
93赞 Martijn Pieters 10/7/2019
如果要打印异常,最好使用 ;基本实现仅返回异常消息,而不返回类型。或者,使用该模块,该模块具有用于打印当前异常、格式化或完整回溯的方法。print(repr(e))Exception.__str__traceback
3赞 Hi-Angel 12/18/2020
@MartijnPieters没有给出任何跟踪跟踪。from traceback 模块(在另一个答案中提到)在这种情况下有效。print(repr(e))print_exc
8赞 Martijn Pieters 12/25/2020
@Hi-Angel:我在哪里声称打印会给堆栈跟踪?我说的是 和 之间的区别,后者包含更多信息,您也可以在回溯的最后一行中看到这些信息。我在评论中明确提到了该模块。repr(e)str(e)repr(e)traceback
782赞 Cat Plus Plus 9/27/2009 #3

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

import traceback

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

输出:

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

评论

9赞 MikeSchem 3/28/2018
有没有某种get_error_message调用,当我使用自己的打印例程添加其他东西时,我可以打印。
62赞 heyzling 2/9/2019
@MikeSchemerror_message = traceback.format_exc()
3赞 aaronsteers 8/20/2019
此截断不使用捕获的异常对象。你能扩展代码以使用“ex”吗?- 如...except Exception as ex:
7赞 Martijn Pieters 10/7/2019
@aaronsteers它确实使用捕获的异常;在异常处理程序中,当前异常可通过函数获得,函数从那里获取它。只有在不处理异常或想要显示基于其他异常的信息时,才需要显式传入异常。sys.exc_info()traceback.print_exc()
6赞 aaronsteers 10/10/2019
是的,我有时想保留异常并稍后打印它,当我不再在“除外”块中时。
4赞 whatnick 9/27/2009 #4

如果这是您想要执行的,则可以使用断言语句来完成一次行错误引发。这将帮助您编写静态可修复的代码并尽早检查错误。

assert type(A) is type(""), "requires a string"

评论

0赞 Alois Mahdal 6/29/2022
assert语句不应用于正常逻辑;如果 Python 使用 .参见 python(1)。-O
201赞 ilya n. 9/28/2009 #5

Python 2.6 或更高版本中,它更简洁一些:

except Exception as e: print(e)

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

except Exception, e: print e
76赞 grish 9/22/2018 #6

(我本来打算把这个作为对@jldupont回答的评论,但我没有足够的声誉。

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

except Exception as e:
    print(e)

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

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

(请注意,您必须这样做才能正常工作。这样,错误被打印到 而不是 ,这允许正确的输出解析/重定向/等。我知道这个问题严格来说是关于“打印错误”的,但在这里指出最佳实践似乎很重要,而不是遗漏这个细节,因为这些细节可能会导致任何最终没有学得更好的人使用非标准代码。import sysSTDERRSTDOUT

我没有像 Cat Plus Plus 的回答那样使用过该模块,也许这是最好的方法,但我想我会把它扔在那里。traceback

评论

4赞 Cameron Kerr 2/11/2019
我建议进一步添加flush=True。我注意到使用 systemd(并且没有使用适当的日志记录框架),捕获到日志时的缓冲不是我所期望的。
0赞 avighnac 3/21/2023
@CameronKerr“stderr”不是没有缓冲的?
129赞 winklerrr 10/30/2019 #7

Python 3:logging

可以使用更灵活的日志模块来记录异常,而不是使用基本功能。该模块提供了许多额外的功能,例如,记录消息......print()logging

  • 添加到给定的日志文件中,或者
  • 带有时间戳和有关日志记录发生位置的其他信息。

有关更多信息,请查看官方文档


用法

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

import logging

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

输出

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 

笔记

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

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


备用日志级别

也可以使用另一个日志级别记录异常,但仍然使用关键字参数显示异常详细信息,如下所示:exc_info=True

logging.critical("An exception was thrown!", exc_info=True)
logging.error   ("An exception was thrown!", exc_info=True)
logging.warning ("An exception was thrown!", exc_info=True)
logging.info    ("An exception was thrown!", exc_info=True)
logging.debug   ("An exception was thrown!", exc_info=True)

# or the general form
logging.log(level, "An exception was thrown!", exc_info=True)

仅名称和描述

当然,如果你不想要整个回溯,而只想要一些特定的信息(例如,异常名称和描述),你仍然可以像这样使用该模块:logging

try:
    1/0
except BaseException as exception:
    logging.warning(f"Exception Name: {type(exception).__name__}")
    logging.warning(f"Exception Desc: {exception}")

输出

WARNING:root:Exception Name: ZeroDivisionError
WARNING:root:Exception Desc: division by zero

评论

6赞 Prakhar Pandey 1/24/2020
不应在日志记录处理程序中使用以避免 RecursionError
0赞 sqqqrly 4/3/2023
在此示例中,将记录异常,并将异常“处理”。如果处理不充分,人们可能希望重新提出这一例外。
0赞 Convexity 8/23/2023
这个“logging.exception()”很棒!它对我来说效果很好。相反,当我在其他答案中记录“异常”或任何内容时,有时它运行良好,有时它打印了另一个“错误”,有时它没有告诉错误的文件名和行号,有时它记录了错误的文件和行号。
68赞 GinTonic 4/15/2020 #8

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

代码

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

将产生以下回溯:

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'

打印/记录完整的回溯

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

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

这将产生以下输出:

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'

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

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

输出:

__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'

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

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

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

输出:

Exception: FileNotFoundError
Exception message: [Errno 2] No such file or directory: 'not_existing_file.txt'

评论

8赞 LarsH 8/11/2020
希望我能多次为这个答案投赞成票,因为它比公认的答案更有帮助。
0赞 pigeonburger 9/9/2020
在您的答案中的最后一部分(“仅打印/记录错误名称\消息”),我如何同时打印两者并且只使用一次?每当我尝试这样做时,结果都很奇怪。ExceptionException Messageprint
1赞 theProCoder 10/22/2021
print(f"Exception: {type(exception).__name__}\nException message: {exception}").开头的 表示它是一个 ,它只允许您将表达式放在大括号中,而不是使用 。 但是,仅适用于运行 Python 3.6+ 的系统ff-string.format()f-strings
64赞 Liam Roberts 4/16/2021 #9

从“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}")

输出:

ZeroDivisionError at line 48 of /Users/.../script.py: division by zero

评论

2赞 Trishant Pahwa 7/29/2022
最有用的答案。
1赞 doplano 1/12/2023
对我来说,在 Python 3.7 Anaconda 中只返回任何其他内容pint(e)Message:
0赞 izzulmakin 7/9/2023
不得不向下滚动太远才能得到真正的答案。
4赞 alio 7/29/2021 #10

我建议使用 try-except 语句。此外,日志记录异常不是使用 print 语句,而是在记录器上记录一条级别为 ERROR 的消息,我发现这比打印输出更有效。此方法应仅从异常处理程序调用,如下所示:

import logging

try:
    *code goes here*
except BaseException:
    logging.exception("*Error goes here*")

如果你想了解有关日志记录和调试的更多信息,此 python 页面上有很好的文档。

评论

0赞 Melendowski 10/20/2022
在 repl 中很难判断,我认为这会打印异常但不会停止程序是否正确?也就是说,我仍然可以优雅地退出。
36赞 Raj Maddheshiya 2/20/2022 #11

试试这个

try:
    print("Hare Krishna!")
except Exception as er:
    print(er)

评论

12赞 Simas Joneliunas 2/24/2022
通常没有解释的代码块不是一个很好的答案。如果你能告诉我们为什么我们应该尝试这段代码,以及为什么它会/可能会帮助操作,这对社区有更大的帮助。