Python C api-函数重载

Python C api-函数重载,python,overloading,python-c-api,Python,Overloading,Python C Api,我有许多接受不同参数的C函数,例如 foo_i(int a) foo_c(char c) 在python C api中是否可以重载这些函数 我尝试使用下表中的方法: static PyMethodDef test_methods[] = { {"foo", (PyCFunction)foo_i, METH_VARARGS, "int"}, {"foo", (PyCFunction)foo_c, METH_VARARGS, "char"}, {NULL, NULL, 0

我有许多接受不同参数的C函数,例如

foo_i(int a)

foo_c(char c)
在python C api中是否可以重载这些函数

我尝试使用下表中的方法:

static PyMethodDef test_methods[] = {
    {"foo", (PyCFunction)foo_i, METH_VARARGS, "int"},
    {"foo", (PyCFunction)foo_c, METH_VARARGS, "char"},
    {NULL, NULL, 0, NULL}
};
但是当我从python调用foo时,我总是使用表底部的函数

关于如何在python c-api中使用foo()调用foo_i()foo_c()有什么想法吗


谢谢

要么给它们不同的Python级别名称,要么编写一个包装函数,该函数的类型检查提供的参数并分派给正确的“real”函数。Python本身不直接支持基于参数类型重载函数

如果您希望为您编写包装,您可以查看一下
pybind11
,它确实允许您尝试重载(它是通过引擎盖下的类型检查包装实现的,因此它只是语法上的糖分,而不是行为上的改变)

未经测试的示例代码:

静态PyObject*
foo_包装器(PyObject*self,PyObject*arg)
{
Py_缓冲区视图;
比尤西瓦尔;
//检查/处理长度为1字节的对象(字节、字节数组、小mmap等)
if(PyObject_GetBuffer(arg,&view,PyBUF_SIMPLE)==0){
如果(view.len!=1){
PyErr_格式(PyExc_ValueError,“必须只接收一个字节,得到%zd”,view.len);
PyBuffer_发布(&view);
返回NULL;
}
foo_c(((char*)view.buf)[0]);
Py_RETURN\u NONE;//或转换来自foo_c的返回(如果存在)
}
//检查/处理适合C int的类整数对象
PyErr_Clear();//忽略不支持缓冲区协议的对象的错误
ival=PyNumber\u ASSIZE\u t(参数,PyExc\u值错误);
如果(Pyrr_发生()){
if(PyErr\u异常匹配(PyExc\u类型错误)){
//替换为关于两种接受参数类型的常规错误消息,
//因为只有从int转换报告错误可能会让人困惑
PyErr_格式(PyExc_TypeError,“参数长度必须为1字节,如object或integer;收到%R”,Py_类型(arg));
}
返回NULL;
}
//检查有效范围(Py\u ssize\t通常大于int)
如果(ivalINT\u MAX){
返回PyErr_格式(PyExc_ValueError,“整数必须在[%d-%d]范围内;收到%zd”、INT_MIN、INT_MAX、ival);
}
福乌一世((国际)伊瓦尔);
Py_RETURN\u NONE;//或转换来自foo\u i的返回(如果存在)
}
静态PyMethodDef测试方法[]={
{“foo”,(PyCFunction)foo_wrapper,METH_O,“foo_c和foo_i的wrapper”},
{NULL,NULL,0,NULL}
};

谢谢!如何在Python-C-api中编写包装器类型检查函数?@PintoDoido:对于这样的单个参数,您只需编写一个
METH\O
函数(接受两个
PyObject*
参数,其中第一个参数被忽略,返回一个
PyObject*
),然后获取第二个参数并键入check并分派给相应的“real”函数。我发布了示例代码(未测试,不转换返回结果,因为我不知道每个函数返回什么)。