Python C API, 如何从子类型调用基类型方法?

Python C API, How to call base type method from subtype?

我按照本指南 Python C API Defining New Types

使用 C API 从一个现有的 Python 类型创建了一个子类型

由于新 PyTypeObject 的 tp_methods 属性,我通过注册新方法覆盖了一种基类型的方法。 这工作正常。

但是,代码还必须能够执行基类型方法(已被覆盖的方法。我找不到有关如何执行此操作的文档。

欢迎任何想法,谢谢

我认为有 2.5 个选项,按复杂程度排序:

  1. 只要找到定义它的C函数即可。当使用 C API 时,您很可能是从 C 中实现的已知 class 继承的。在这种情况下,您将找到用于该方法的 C 函数并调用它。

  2. 从对象中得到class,从class中得到基数:

    一个。 PyObject* baseclass = self->ob_type->tp_base;

    b。使用 super() 的 C API 等价物:

    PyObject* baseclass = PyObject_CallFunctionObjArgs(&PySuper_Type,self->ob_type,self,NULL);

    找到基础后,您就可以使用 C API 等效的 getattr 来获取相关函数:

.

/* check baseclass against null */
PyObject* func = PyObject_GetAttrString(baseclass,"function_name");
/* check func is not null */
PyObject* result = PyObject_CallFunctionObjArgs(self,other_arguments..., NULL); /* adjust arguments here */
Py_DECREF(func);
// decref result?

您可以使用不同的调用方法,但您需要确保将参数传递给 self。


选项 2b 可能是最灵活的,因为它应该在通过 tp_bases.

定义多个碱基时起作用

我 post 这里我的工作代码很大程度上受到了 DavidW 回答的启发。修改为:
1/将子类型对象实例(自身)转换为 PyObject 指针以供 ob_type 访问。 2/ 使用 func 作为 PyObject_CallFunctionObjArg 第一个参数而不是 self.

PyObject* baseclass = ((PyObject*)self)->ob_type->tp_base;
if (baseclass == NULL) {...}
PyObject* func = PyObject_GetAttrString(baseclass,"sum");
if (func == NULL) { ... }
PyObject* result = PyObject_CallFunctionObjArgs(func,self, NULL);
Py_DECREF(func);