在Python中,MemoryError和OverflowError有什么区别?

3

看起来两种异常在类似的情况下都会被触发。

这两行代码背后发生了什么,它们之间有什么区别?

>>> (i for i in range(1000000000)) # 10^9
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
MemoryError
>>> (i for i in range(10000000000)) # 10^10
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: range() result has too many items
2个回答

4
在第一个例子中,您试图将包含 10 亿个整数的列表传递给生成器表达式。您的计算机尝试创建该列表时会耗尽内存。在 Python 3 中,我认为这将起作用,因为 range 本身会生成一个生成器,而不是显式列表。
在第二个例子中,我认为 range 在您的计算机上需要一个 32 位值作为其输入,因此会在耗尽内存之前抛出不同的错误。

你说得对 - 我使用32位的Python。 1000000000 < 2^32 < 10000000000 - zvisofer

2

来自文档:

异常 OverflowError

当算术运算的结果太大无法表示时引发。对于长整型(它们通常会引发 MemoryError 而不是放弃),以及大多数普通整数的操作,这种情况不会发生,因为它们会返回长整数。由于 C 中浮点异常处理缺乏标准化,大多数浮点操作也不会被检查。

异常 MemoryError

当某个操作耗尽内存但情况仍可挽救(通过删除一些对象)时引发。相关值是一个字符串,指示哪种(内部)操作的内存用完了。请注意,由于底层内存管理体系结构(C 的 malloc() 函数),解释器可能无法总是完全恢复到此状态;尽管如此,它仍会引发异常,以便在程序失控时可以打印堆栈回溯。

在 Python 2 中,range(1000000000) 生成一个具有 1000000000 个元素的列表,导致你的内存耗尽。如果你使用生成器 xrange 替换 range,问题就会消失。

在第二个示例中,1000000000 实际上是一个长整型。如果你使用 xrange,你将得到:

>>> (i for i in xrange(10000000000))
OverflowError: long int too large to convert to int

3
但第一个示例会产生MemoryError错误,反之亦然。 - RussW

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接