以下代码:
class Container:
def __len__(self):
return 10**100
c = Container()
print(len(c))
Run Code Online (Sandbox Code Playgroud)
返回
溢出错误:无法将“int”放入索引大小的整数中
我读过这个问题已被标记为 WON'T FIX但也许它已在另一个问题中修复?除了使用自定义属性来存储容器大小之外,还有其他解决方法吗?
我使用的是 Python 3.6.9,但在此版本中尚未修复。
这并没有以任何方式改变,也没有解决方法。它是一个文档化的 CPython 实现细节。
object.__len__(self)调用以实现内置函数
len()。应该返回对象的长度,一个整数>= 0。此外,未定义__bool__()方法且其__len__()方法返回零的对象在布尔上下文中被认为是假的。CPython 实现细节:在 CPython 中,长度最多为
sys.maxsize. 如果长度大于sys.maxsize某些特征(例如len())可能会引发 OverflowError。为了防止OverflowError被真值测试引发 ,一个对象必须定义一个__bool__()方法。
请注意,最大值是9223372036854775807在 64 位机器上。
sys.maxsize
一个整数,给出 Py_ssize_t 类型的变量可以采用的最大值。它通常
2**31 - 1在 32 位平台和2**63 - 164 位平台上。
该限制是由于__len__是多个 C-API 调用的 Python 表示,以获取容器长度。C-APIPy_ssize_t为此需要一种类型,它具有观察到的限制。
Py_ssize_t PySequence_Length(PyObject *o)
o在成功和-1失败时依次返回对象的数量。这相当于 Python 表达式len(o)。
由于OverflowError是记录在案的行为,因此对于可能太大而__len__无法提供它的对象来说是可以接受的。例如,内置range函数可以溢出len:
>>> import sys
>>> len(range(sys.maxsize))
9223372036854775807
>>> len(range(sys.maxsize + 1))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: Python int too large to convert to C ssize_t
Run Code Online (Sandbox Code Playgroud)
如果需要精确的长度,对象可以自由地实现一个单独的方法来返回长度而不使用len.
| 归档时间: |
|
| 查看次数: |
111 次 |
| 最近记录: |