当我用 Python3 的 C API 构建 PyObject 时,它的 ob_type 是 NULL

when I build a PyObject with C API of Python3, its ob_type is NULL

我在C++11中运行这样的代码:

PyObject* aa = PyLong_FromLong(7L);

然后我查看了aa的值,不是NULL,而是aa->ob_typeNULL

然而,当我运行:

PyObject* aa = PyLong_FromLong(257L);

aa->ob_type 不再是 NULL。我看了PyLong_FromLong的文档,发现了这个:

PyObject* PyLong_FromLong(long v)
Return value: New reference. 
Return a new PyLongObject object from v, or NULL on failure.

The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object. So it should be possible to change the value of 1. I suspect the behaviour of Python in this case is undefined. :-)

似乎在-5和256之间构建PyLongObject时会遇到这个问题。但是我不明白原因。

更重要的是,这个问题在Python2中没有出现。太不可思议了!

您还没有初始化 Python。由于这些小对象是特殊情况,它们是在 Python 初始化时设置的。

#include <Python.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
  Py_Initialize();
  PyObject* aa = PyLong_FromLong(7L);
  printf("aa=%d\naa->ob_type=%p\n",PyLong_AsLong(aa),aa->ob_type);
  Py_Finalize();
  return 0;
}

正确打印

aa=7

aa->ob_type=0x7f380d6b5800 (note that this will vary from run to run)

如果我注释掉 Py_Initialize()Py_Finalize() 然后我得到一个分段错误,但是如果我不尝试用 PyLong_AsLong 读取值然后我得到一个空指针ob_type.


The documentation 确实告诉你初始化解释器。


相对于 Python2 它有两个整数类型 PyIntPyLong PyInt 处理小值,因此具有特殊情况 table.如果您在 Python2 中使用 PyInt,您可能会遇到同样的问题。在调用 Py_Initialize 之前用 Python 做的任何事情都是未定义的,所以它可能会以不同的令人兴奋的方式失败。