为什么int(maxint)给出一个long,但int(int(maxint))给出一个int?这是一个NumPy错误吗?

Meh*_*dad 14 python int numpy python-2.7 long-integer

非常不言自明(我在Windows上):

>>> import sys, numpy
>>> a = numpy.int_(sys.maxint)
>>> int(a).__class__
<type 'long'>
>>> int(int(a)).__class__
<type 'int'>
Run Code Online (Sandbox Code Playgroud)

为什么叫int一次给我一个long,而两次叫它给我一个int

这是一个错误还是一个功能?

Ant*_*ala 4

这个问题特定于 Numpy 和 Python 2。在 Python 3 中没有单独的intlong类型。

该行为的发生是由于 numpy 中的相差一错误所致。int(x)通过调用1 个参数将其转换x为数字PyNumber_Int(x)PyNumber_Int然后专门采用子类的路径int,因为int64返回的numpy.int_是 的子类int

m = o->ob_type->tp_as_number;
if (m && m->nb_int) { /* This should include subclasses of int */
    /* Classic classes always take this branch. */
    PyObject *res = m->nb_int(o);
    if (res && (!PyInt_Check(res) && !PyLong_Check(res))) {
        PyErr_Format(PyExc_TypeError,
                     "__int__ returned non-int (type %.200s)",
                     res->ob_type->tp_name);
        Py_DECREF(res);
        return NULL;
    }
    return res;
}
Run Code Online (Sandbox Code Playgroud)

现在,对于此代码调用,它在numpy/core/src/umath/scalarmath.c.srca->ob_type->tp_as_number->nb_int中实现。这是针对不同类型进行参数化的代码的位置;这个方法用于填充方法槽。它有以下减一:<typename>_intnb_intif

if(LONG_MIN < x && x < LONG_MAX)
    return PyInt_FromLong(x);
Run Code Online (Sandbox Code Playgroud)

两个运算符都应该<=代替。在<那里,既没有LONG_MIN也没有LONG_MAX通过条件,而是在第 1432 行将它们转换PyLonga

return @func@(x);
Run Code Online (Sandbox Code Playgroud)

在 的情况下@func@被替换为。因此,被返回。PyLong_FromLongLongint_long(sys.maxint)

现在,由于sys.maxint仍然可以用 表示intint(long(sys.maxint))因此返回int; 同样int(sys.maxint + 1)返回一个long.