Python 中字符串为空的内存错误消息

MemoryError's message as str is empty in Python

这是一个非常愚蠢的问题,但我正在 运行 一些任务并通过以下方式捕获它们的错误:

try:
    run_something()
except Exception as e:
    handle_error(str(e))

我希望将错误消息作为字符串,因为我正在使用 UI 并且我想在 window.

中显示错误

问题可以复制为:

>>> import numpy as np
>>> np.range(1e10)
MemoryError                               Traceback (most recent call last)
<ipython-input-4-20a59c2069b2> in <module>() 
----> 1 np.arange(1e10)

MemoryError: 

但是,如果我尝试捕获错误并打印其消息(我希望它是 "MemoryError":

try:
    np.arange(1e10)
except Exception as e:
    print(str(e))
    print("Catched!")

我得到的唯一输出是 "Catched!"。这太愚蠢了,我正在用 UI 和线程做一些工作,我花了一段时间才意识到问题是内存错误,根本没有任何消息。

MemoryError 是唯一被转换为空字符串的异常吗?因为如果是这样,我可以检查它。如果不是,如何将其消息作为字符串获取?

所以你可能想打印异常的 name class:

try:
    np.arange(1e10)
except Exception as e:   #not catch...
    print(str(e.__class__.__name__))
    print("Catched!")

使用 str(e) 仅打印异常的 "message",在您的情况下它是空的。


请注意,您可以通过 args 属性获取传递给异常构造函数的参数:

In [4]: try:
   ...:     raise ValueError(1,2,3)
   ...: except ValueError as e:
   ...:     print('arguments:', e.args)
arguments: (1, 2, 3)

来自 Python 文档(2.7 版,我想也适用于 Python 3.x):

The base class for all built-in exceptions. It is not meant to be directly inherited by user-defined classes (for that, use Exception). If str() or unicode() is called on an instance of this class, the representation of the argument(s) to the instance are returned, or the empty string when there were no arguments.

似乎 MemoryError 没有参数,因此根据此文档确实返回了一个空字符串。

当然还是可以捕获到异常,因为可以按类型捕获。

您可以获得异常的名称 class 并打印它。

这当然也很有意义,因为看看那个:

a = {}
try:
    a['barrel']
except Exception as e:
    print str(e)

只会打印 'barrel' -- 没什么帮助,所以添加异常的 class 名称确实是个好主意:

...
except Exception as e:
    print(e.__class__.__name + ': ' + (str(e)))

当调用str(e)时,它returns异常消息。举个例子-

NameError: name 'a' is not defined
^          ^
name       message

:之前的部分是异常的名称,而在它之后的部分是消息(参数)。

MemoryError 的情况下,如您在示例中所见 -

MemoryError:

没有错误消息,只有异常的名称,因此您得到空字符串。

我不确定是否还有其他没有异常的异常,但我相信找到这样的异常是非常罕见的。也许你可以同时打印异常的名称和消息,如果你真的想处理 MemoryError(可能还有其他没有消息的罕见异常),比如 -

print(type(e).__name__ , ':', str(e))