首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >CPython‘重载’函数

CPython‘重载’函数
EN

Stack Overflow用户
提问于 2019-11-27 18:45:19
回答 1查看 122关注 0票数 0

我正在尝试重载一个python扩展函数,该函数将接受一个对象或一个字符串。

代码语言:javascript
复制
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

下面是这个PyArg_ParseTuple的Python:

int PyArg_ParseTuple(PyObject *args,const char *PyArg_ParseTuple,.)

解析只将位置参数放入局部变量的函数的参数。在成功时返回true;如果失败,则返回false并引发适当的异常。

我猜想PyArg_ParseTuple设置了一个错误,这导致整个函数不能工作(我的模块方法表中有customFunction,我只是省略了这段代码)。如果我有以下Python:

代码语言:javascript
复制
import CustomModule

try:
  CustomModule.customFunction("foo")
except Exception as e:
  print("Error:", e)

String function确实会被输出,所以字符串if语句中的代码确实有效,但是我假设发生错误是因为对象的PyArg_ParseTuple失败了,所以它返回一个错误(不能100%确定这是否正确)。

有什么方法可以防止PyArg_ParseTuple()引发错误,是否还有其他函数,或者是否有更好的方法来“重载”我的自定义函数?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-27 19:37:41

我可能只需要使用PyArg_ParseTuple获取一个通用的未指定对象,然后使用Py*_Check处理对象类型。

代码语言:javascript
复制
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的“请求宽恕,而不是许可”模式

代码语言:javascript
复制
try:
    something()
except SomeException:
    somethingElse()

并不能很好地转换成C,并且涉及到相当多的代码来处理异常。如果您真的想这样做,那么您需要在第二个PyErr_Clear之前调用PyArg_ParseTuple,理想情况下,您应该检查它是您认为的例外,而不是完全其他的东西。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59076682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档