CPython 'overloaded' 函数
CPython 'overloaded' functions
我正在尝试重载一个 python 扩展函数,该函数需要一个对象或一个字符串。
typedef struct
{
PyObject_HEAD
} CustomObject;
PyObject* customFunction(CustomObject* self, PyObject* args);
PyMethodDef methods[] =
{
{"customFunction", (PyCFunction) customFunction, METH_VARAGS, "A custom function"},
{NULL}
}
PyTypeObject TypeObj =
{
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "customModule.CustomObject",
.tp_doc = "Custom Object",
.tp_basicsize = sizeof(CustomObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_methods = methods,
}
// Area of problem
PyObject* customFunction(CustomObject* self, PyObject* args)
{
const char* string;
PyObject* object;
if (PyArg_ParseTuple(args, "O!", &TypeObj, &object)) // TypeObj is the PyTypeObject fpr CustomObject
{
std::cout << "Object function\n"
// Do whatever and return PyObject*
}
else if (PyArg_ParseTuple(args, "s", &string))
{
std::cout << "String function\n"
// Do whatever and return PyObject*
}
return PyLong_FromLong(0); // In case nothing above works
}
在 python 中,我尝试了除函数之外的其他功能,但出现此错误 Error: <built-in method customFunction of CustomModule.CustomObject object at 0xmemoryadress> returned a result with an error set
这里是 Python 文档PyArg_ParseTuple:
int PyArg_ParseTuple(PyObject *args, const char *format, ...)
Parse the parameters of a function that takes only positional parameters into local variables. Returns true on success; on failure, it returns false and raises the appropriate exception
我猜测 PyArg_ParseTuple 正在设置一个错误,这导致整个函数无法工作(我的模块方法 table 中确实有 customFunction,我只是忽略了它代码)。如果我有以下 Python:
import CustomModule
try:
CustomModule.customFunction("foo")
except Exception as e:
print("Error:", e)
String function
确实输出了,所以字符串 if 语句中的代码确实有效,但我假设错误发生是因为对象的 PyArg_ParseTuple 失败,所以它 returns 一个错误(不能 100% 确定这是否正确)。
有什么方法可以防止 PyArg_ParseTuple() 引发错误,是否有其他函数,或者是否有更好的方法来 'overload' 我的自定义函数?
我可能只是使用 PyArg_ParseTuple
来获取通用的未指定对象,然后稍后使用 Py*_Check
:
处理对象类型
if (!PyArg_ParseTuple(args, "O", &object)) {
return NULL;
}
if (PyObject_IsInstance(object, (PyObject*)&PyType)) { // or a more specific function if one exists
std::cout << "Object function\n";
} else if (PyUnicode_Check(object)) {
std::cout << "String function\n";
} else {
// set an error, return NULL
}
原因是 Python "ask forgiveness, not permission" 模式
try:
something()
except SomeException:
somethingElse()
不能很好地转换为 C,并且涉及相当多的代码来处理异常。如果你真的想那样做,那么你需要在第二个PyArg_ParseTuple
之前调用PyErr_Clear
,理想情况下你应该检查它是否是你认为的异常,并且完全不是别的东西。
我正在尝试重载一个 python 扩展函数,该函数需要一个对象或一个字符串。
typedef struct
{
PyObject_HEAD
} CustomObject;
PyObject* customFunction(CustomObject* self, PyObject* args);
PyMethodDef methods[] =
{
{"customFunction", (PyCFunction) customFunction, METH_VARAGS, "A custom function"},
{NULL}
}
PyTypeObject TypeObj =
{
PyVarObject_HEAD_INIT(NULL, 0)
.tp_name = "customModule.CustomObject",
.tp_doc = "Custom Object",
.tp_basicsize = sizeof(CustomObject),
.tp_itemsize = 0,
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_methods = methods,
}
// Area of problem
PyObject* customFunction(CustomObject* self, PyObject* args)
{
const char* string;
PyObject* object;
if (PyArg_ParseTuple(args, "O!", &TypeObj, &object)) // TypeObj is the PyTypeObject fpr CustomObject
{
std::cout << "Object function\n"
// Do whatever and return PyObject*
}
else if (PyArg_ParseTuple(args, "s", &string))
{
std::cout << "String function\n"
// Do whatever and return PyObject*
}
return PyLong_FromLong(0); // In case nothing above works
}
在 python 中,我尝试了除函数之外的其他功能,但出现此错误 Error: <built-in method customFunction of CustomModule.CustomObject object at 0xmemoryadress> returned a result with an error set
这里是 Python 文档PyArg_ParseTuple:
int PyArg_ParseTuple(PyObject *args, const char *format, ...)
Parse the parameters of a function that takes only positional parameters into local variables. Returns true on success; on failure, it returns false and raises the appropriate exception
我猜测 PyArg_ParseTuple 正在设置一个错误,这导致整个函数无法工作(我的模块方法 table 中确实有 customFunction,我只是忽略了它代码)。如果我有以下 Python:
import CustomModule
try:
CustomModule.customFunction("foo")
except Exception as e:
print("Error:", e)
String function
确实输出了,所以字符串 if 语句中的代码确实有效,但我假设错误发生是因为对象的 PyArg_ParseTuple 失败,所以它 returns 一个错误(不能 100% 确定这是否正确)。
有什么方法可以防止 PyArg_ParseTuple() 引发错误,是否有其他函数,或者是否有更好的方法来 'overload' 我的自定义函数?
我可能只是使用 PyArg_ParseTuple
来获取通用的未指定对象,然后稍后使用 Py*_Check
:
if (!PyArg_ParseTuple(args, "O", &object)) {
return NULL;
}
if (PyObject_IsInstance(object, (PyObject*)&PyType)) { // or a more specific function if one exists
std::cout << "Object function\n";
} else if (PyUnicode_Check(object)) {
std::cout << "String function\n";
} else {
// set an error, return NULL
}
原因是 Python "ask forgiveness, not permission" 模式
try:
something()
except SomeException:
somethingElse()
不能很好地转换为 C,并且涉及相当多的代码来处理异常。如果你真的想那样做,那么你需要在第二个PyArg_ParseTuple
之前调用PyErr_Clear
,理想情况下你应该检查它是否是你认为的异常,并且完全不是别的东西。