英雄菜刀 发表于 2021-1-24 16:07:21

关于Python底层整数类型实现的问题

Python版本号 3.8.6

在阅读Python源码的时候,关于整数类型的实现,我有点小疑惑。
简单看一下小整数的实现(完整代码在最下面),在for循环里,首先看到第一句
size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
这里面size会根据ival的正负来分别取-1/0/1。然后是进行引用计数的更新(由于小整数是一定会天地同寿的这里就不分析了)。
接下来可以看到,代码中的这两行
Py_SIZE(v) = size;
v->ob_digit = (digit)abs(ival);
第二行很显然是把ival对应值取绝对值以后送到存储空间中,但是第一行我就觉得不是特别懂,因为size在这里很显然是ival的符号,但是却赋给了v的size。

进一步地,我看到Py_SIZE的实现
typedef struct {
    PyObject ob_base;
    Py_ssize_t ob_size; /* Number of items in variable part */
} PyVarObject;

/* Cast argument to PyVarObject* type. */
#define _PyVarObject_CAST(op) ((PyVarObject*)(op))

#define Py_SIZE(ob)             (_PyVarObject_CAST(ob)->ob_size)

可以看到,这个Py_SIZE(ob)是将ob->ob_size赋值的一个宏定义。而ob_size对应的是类的元素个数,如果传入一个负值或者0,这个地方岂不是很离谱?还是说Python底层实现的时候对于整数类型的这个地方有什么特殊的处理?

以下是详细代码

# longobject.c
int
_PyLong_Init(void)
{
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
    int ival, size;
    PyLongObject *v = small_ints;

    for (ival = -NSMALLNEGINTS; ival <NSMALLPOSINTS; ival++, v++) {
      size = (ival < 0) ? -1 : ((ival == 0) ? 0 : 1);
      if (Py_TYPE(v) == &PyLong_Type) {
            /* The element is already initialized, most likely
             * the Python interpreter was initialized before.
             */
            Py_ssize_t refcnt;
            PyObject* op = (PyObject*)v;

            refcnt = Py_REFCNT(op) < 0 ? 0 : Py_REFCNT(op);
            _Py_NewReference(op);
            /* _Py_NewReference sets the ref count to 1 but
             * the ref count might be larger. Set the refcnt
             * to the original refcnt + 1 */
            Py_REFCNT(op) = refcnt + 1;
            assert(Py_SIZE(op) == size);
            assert(v->ob_digit == (digit)abs(ival));
      }
      else {
            (void)PyObject_INIT(v, &PyLong_Type);
      }
      Py_SIZE(v) = size;
      v->ob_digit = (digit)abs(ival);
    }
#endif
    _PyLong_Zero = PyLong_FromLong(0);
    if (_PyLong_Zero == NULL)
      return 0;
    _PyLong_One = PyLong_FromLong(1);
    if (_PyLong_One == NULL)
      return 0;

    /* initialize int_info */
    if (Int_InfoType.tp_name == NULL) {
      if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) {
            return 0;
      }
    }

    return 1;
}




°蓝鲤歌蓝 发表于 2021-1-24 18:59:18

你应该发到 C语言交流里
页: [1]
查看完整版本: 关于Python底层整数类型实现的问题