如何使用PyList返回Python C API扩展中的整数列表?

Ale*_*kov 2 c++ python cpython python-c-api python-extensions

我正在.pyd使用Visual Studio 2015 C ++项目和Python 2.7 32位构建Python扩展()。

这是我的.cpp文件:

#include <Python.h>

static PyObject* GetTwoInts(PyObject* self, PyObject* args)
{
    srand(time(NULL));
    int random1 = rand() % 10;
    int random2 = rand() % 10;

    PyObject * python_val = Py_BuildValue("ii", random1, random2);
    return python_val;
}

static PyObject* GetListTwoInts(PyObject* self, PyObject* args)
{
    srand(time(NULL));
    int random1 = rand() % 10;
    int random2 = rand() % 10;

    PyObject *val1 = PyInt_FromLong(random1);
    PyObject *val2 = PyInt_FromLong(random2);

    PyObject *result = PyList_New(2);
    PyList_SetItem(result, 0, val1);
    PyList_SetItem(result, 1, val2);

    PyObject * python_val = Py_BuildValue("ii", result);
    return python_val;
}

PyMODINIT_FUNC initUtils(void)
{
    static PyMethodDef methods[] = {
        { "GetTwoInts", GetTwoInts, METH_NOARGS,
        "Get two C ints as a Python tuple with two random numbers" },

        { "GetListTwoInts", GetListTwoInts, METH_NOARGS,
        "Get a list with two random numbers" },
        { NULL, NULL, 0, NULL },

    };

    PyObject *m = Py_InitModule("Utils", methods);
}
Run Code Online (Sandbox Code Playgroud)

这是使用已编译扩展名的Python源代码:

import sys
import Utils
print help(Utils)
print Utils.GetTwoInts()
print Utils.GetListTwoInts()
Run Code Online (Sandbox Code Playgroud)

这是输出:

(4, 2)
(91213912, 91213912)
Run Code Online (Sandbox Code Playgroud)

因此,Py_BuildValue("ii", random1, random2);正如我所料,给了我一个带有两个随机整数的适当元组。但是,在该GetListTwoInts方法中返回列表会给我无效的数字(看起来像参考值还是指针?)。

我应该怎么做才能在GetListTwoInts方法中返回实数值列表?

psc*_*ill 6

您可以更改的格式,Py_BuildValue以便它构建列表而不是元组。只需使用"[ii]"而不是"ii"作为第一个参数:

static PyObject* GetListTwoInts(PyObject* self, PyObject* args)
{
    srand(time(NULL));
    int random1 = rand() % 10;
    int random2 = rand() % 10;

    PyObject * python_val = Py_BuildValue("[ii]", random1, random2);
    return python_val;
}
Run Code Online (Sandbox Code Playgroud)

如果要创建动态大小列表,可以使用PyList_New和PyList_SetItem。

static PyObject* GetList(PyObject* self, PyObject* args)
{
    srand(time(NULL));
    int const N = 10;
    PyObject* python_val = PyList_New(N);
    for (int i = 0; i < N; ++i)
    {
        int r = rand() % 10;
        PyObject* python_int = Py_BuildValue("i", r);
        PyList_SetItem(python_val, i, python_int);
    }
    return python_val;
}
Run Code Online (Sandbox Code Playgroud)

问题中PyList版本的问题是您Py_BuildValue("ii", result)在列表中使用的版本。这将尝试创建两个整数的元组,其中第一个值是result强制转换为整数的指针。

  • 或者使用`PyList_Append`,这可能是:`PyObject *list = PyList_New(0); 遍历数组/列表;PyList_Append(list, PyFloat_FromDouble(element)); 返回列表;` (2认同)