some_function()
执行时引发异常,因此程序跳转到 except
:
try:
some_function()
except:
print("exception happened!")
如何查看导致异常发生的原因?
原文由 Shang Wang 发布,翻译遵循 CC BY-SA 4.0 许可协议
some_function()
执行时引发异常,因此程序跳转到 except
:
try:
some_function()
except:
print("exception happened!")
如何查看导致异常发生的原因?
原文由 Shang Wang 发布,翻译遵循 CC BY-SA 4.0 许可协议
获取异常对象所属类的名称:
e.__class__.__name__
并且使用 print_exc() 函数还将打印堆栈跟踪,这是任何错误消息的基本信息。
像这样:
from traceback import print_exc
class CustomException(Exception): pass
try:
raise CustomException("hi")
except Exception as e:
print ('type is:', e.__class__.__name__)
print_exc()
# print("exception happened!")
你会得到这样的输出:
type is: CustomException
Traceback (most recent call last):
File "exc.py", line 7, in <module>
raise CustomException("hi")
CustomException: hi
在打印和分析之后,代码可以决定不处理异常而只执行 raise
:
from traceback import print_exc
class CustomException(Exception): pass
def calculate():
raise CustomException("hi")
try:
calculate()
except CustomException as e:
# here do some extra steps in case of CustomException
print('custom logic doing cleanup and more')
# then re raise same exception
raise
输出:
custom logic doing cleanup and more
解释器打印异常:
Traceback (most recent call last):
File "test.py", line 9, in <module>
calculate()
File "test.py", line 6, in calculate
raise CustomException("hi")
__main__.CustomException: hi
在 raise
之后,原始异常继续向上传播调用堆栈。 ( 当心可能的陷阱)如果你提出新的异常,它会带来新的(更短的)堆栈跟踪。
from traceback import print_exc
class CustomException(Exception):
def __init__(self, ok):
self.ok = ok
def calculate():
raise CustomException(False)
try:
calculate()
except CustomException as e:
if not e.ok:
# Always use `raise` to rethrow exception
# following is usually mistake, but here we want to stress this point
raise CustomException(e.ok)
print("handling exception")
输出:
Traceback (most recent call last):
File "test.py", line 13, in <module>
raise CustomException(e.message)
__main__.CustomException: hi
注意回溯如何不包括 calculate()
行中的函数 9
这是原始异常的起源 e
。
原文由 Alex 发布,翻译遵循 CC BY-SA 4.0 许可协议
4 回答4.4k 阅读✓ 已解决
4 回答3.8k 阅读✓ 已解决
1 回答3k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
1 回答4.5k 阅读✓ 已解决
1 回答3.8k 阅读✓ 已解决
1 回答2.8k 阅读✓ 已解决
其他答案都指出您不应该捕获通用异常,但似乎没有人想告诉您原因,这对于理解何时可以打破“规则”至关重要。 这 是一个解释。基本上,这样你就不会隐藏:
因此,只要您注意不做任何这些事情,就可以捕获通用异常。例如,您可以通过另一种方式向用户提供有关异常的信息,例如:
那么如何捕捉泛型异常呢?有几种方法。如果您只想要异常对象,请这样做:
确保
message
以一种不容错过的方式引起用户的注意!如果消息隐藏在许多其他消息中,打印它,如上所示,可能还不够。没有引起用户的注意,就等于吞下了所有的例外,如果你在阅读本页的答案后有一个印象,那就是这 _不是一件好事_。以raise
语句结束 except 块将通过透明地重新引发捕获的异常来解决问题。上面和只使用
except:
没有任何参数的区别是双重的:except:
不会给你异常对象来检查SystemExit
,KeyboardInterrupt
和GeneratorExit
没有被上面的代码捕获,这通常是你想要的。请参阅 异常层次结构。如果您还想要在未捕获异常的情况下获得相同的堆栈跟踪,则可以这样获得(仍在 except 子句中):
如果您使用
logging
模块,您可以将异常打印到日志(连同一条消息),如下所示:如果您想深入挖掘并检查堆栈、查看变量等,请使用 except 块内的
pdb
模块的post_mortem
函数:在寻找错误时,我发现最后一种方法非常有用。