В этой задаче я имею дело с адресными пространствами сети 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.
Любые предложения о том, как с этим справиться, или намек на то, что это может быть ограничение, с которым я застрял?
1 ответ
Проблема, с которой вы сталкиваетесь, заключается в том, что C API Python имеет системно-зависимое ограничение на длину контейнеров. То есть функция C PyObject_Size
возвращает значение Py_ssize_t
, которое является подписанной версией стандартного типа C size_t
. Его размер зависит от системы, но, вероятно, 32-битный в 32-битных системах и 64-битный в 64-битных системах.
Встроенная функция len
использует PyObject_Size
, поэтому имеет те же ограничения. Вот его текущая реализация:
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()
Это чистый питон, поэтому у него нет ограничений на целочисленный размер.
__len__
должен вернуть «целое число». Очень большое целое число по-прежнему остается целым.
Похожие вопросы
Новые вопросы
python
Python — это мультипарадигмальный многоцелевой язык программирования с динамической типизацией. Он предназначен для быстрого изучения, понимания и использования, а также обеспечивает чистый и унифицированный синтаксис. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Если у вас есть вопросы о версии Python, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas, NumPy) укажите это в тегах.
len(IP('2001::/64'))
дает мнеTypeError: __len__() should return an int
, тогда какIP('2001::/64').__len__()
дает мне18446744073709551616L
. Что вам даетIP('2001::/64').__len__()
?.__len__()
, работающим нормально, иlen()
, вызывающим исключение.OverflowError: cannot fit 'int' into an index-sized integer
. Это может оказаться просто примечанием к документации для использованияx.len()
, а неlen(x)
.