在C与python交互时,如何实现参数个数不确定的传递?

在python中调用C实现的模块,想在python和C之间根据需要传递参数,但参数个数是不确定的,可以变化的。请问该如何实现?

现在看到的接口都是得确定参数个数,并且需要指定参数类型的,比如:
PyArg_ParseTuple(pTuple, "ifs" , &i, &f, &s)。

或者简化到,传递的参数类型是一致的,但是参数个数可变该如何实现?
比如说有时希望传递10个整数,下次希望传递20个参数?

阅读 3.1k
1 个回答

传入可变参数时,用 PyTuple_Size() 获取参数个数,然后用 PyTuple_GetItem() 循环读取每个参数值,最后根据情况转换参数值。

请参考下面的代码

/*
此 python 扩展示例代码,计算整数数组和,如下:
    from liyi import psum
    psum(1, 2)
    psum(10, 20, 30)
    try:
        psum('a', 1)
    except TypeError:
        pass


## 编译命令(以 linux 为例)
cc -g -Wall `python3.6-config --cflags` -o demo demo.c  `python3.6-config --ldflags`


## 参考
https://docs.python.org/3/c-api/index.html
 */
#include <Python.h>


// 计算整数数组和
static PyObject* psum(PyObject *self, PyObject *args)
{
    int sum = 0;
    for (int i=0; i<PyTuple_Size(args); i++) {
        PyObject *item = PyTuple_GetItem(args, i);
        // 数组元素必须是整型
        if (!PyLong_Check(item)) {
            char message[128];
            snprintf(message, sizeof(message), "%d-th item must be long", i);
            PyErr_SetString(PyExc_TypeError, message);
            return NULL;
        }
        sum += PyLong_AsLong(item);
    }
    return PyLong_FromLong(sum);
}

static PyMethodDef Methods[] = {
    {"psum", psum, METH_VARARGS, "Return sum of integer array"},
    {NULL, NULL, 0, NULL}
};

static PyModuleDef Module = {
    PyModuleDef_HEAD_INIT,
    "liyi", NULL, -1, Methods,
    NULL, NULL, NULL, NULL
};

static PyObject* PyInit(void)
{
    return PyModule_Create(&Module);
}

int main(int argc, char *argv[])
{
    PyImport_AppendInittab("liyi", &PyInit);

    Py_Initialize();
    PyRun_SimpleString(
        "from liyi import psum\n"
        "for numbers in [(1,2), (10,20,30)]:\n"
        "    print('%s = %d' % ('+'.join(map(str, numbers)), psum(*numbers)))\n"
        "try:\n"
        "    psum('a', 1)\n"
        "except TypeError:\n"
        "    import traceback; traceback.print_exc()\n"
    );
    if (Py_FinalizeEx() < 0) {
        exit(1);
    }
    return 0;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题