在这个问题中,我正在处理IPv6网络地址空间,因此长度为2^(128-subnet)
。
似乎python(至少在这台机器上)将处理最多64位有符号数作为__len__()
的返回值。因此len(IP('2001::/66'))
有效,但len(IP('2001::/65'))
失败。
from IPy import IP
len(IP('2001::/64'))
Traceback (most recent call last):
File "test.py", line 2, in <module>
len(IP('2001::/64'))
OverflowError: long int too large to convert to int
有问题的IPy库位于https://github.com/haypo/python-ipy。
有关如何处理此问题的任何建议,或暗示这可能是我遇到的限制?
答案 0 :(得分:13)
您遇到的问题是Python的C API对容器的长度有依赖于系统的限制。也就是说,C函数PyObject_Size
返回Py_ssize_t
值,这是标准C size_t
类型的签名版本。它的大小取决于系统,但在32位系统上可能为32位,在64位系统上可能为64位。
内置len
函数使用PyObject_Size
,因此它具有相同的限制。这是its current implementation:
static PyObject *
builtin_len(PyObject *self, PyObject *v)
{
Py_ssize_t res;
res = PyObject_Size(v);
if (res < 0 && PyErr_Occurred())
return NULL;
return PyInt_FromSsize_t(res);
}
您可以使用len
对象上的IP
方法解决此限制,而不是调用内置len
:
IP('2001::/64').len()
这是纯python,因此它对整数大小没有任何限制。