使用Python3 C API覆盖对象方法

时间:2017-11-27 03:31:17

标签: python c

我正在努力将项目的核心功能从python移植到C,但希望保留调用模块化Python组件的能力。所以我在我的项目中嵌入了python解释器。我已经到了可以在C端和Python端到另一端进行调用的位置,并且共享数据被转换并正确处理。

但是,我似乎无法覆盖我定义的Python类中的方法。相反,没有错误,但我的self没有设置PyCFunction

基本示例代码如下:

  

component.py

class Component(object):
  def my_function(self):
    print("orig function")


class CompObj(Component):
  def test(self):
    self.my_function()
  

example.c

#include <Python.h>

static PyObject *my_function_override(PyObject *self, PyObject *args) {
  printf("Override method %p\n", self);
  return Py_None;
}

PyMethodDef override_method = {
  "my_function",
  (PyCFunction)my_function_override,
  METH_VARARGS,
  NULL
};

int main () {
  wchar_t *program;
  PyObject *sys_path,  *module_path;
  PyObject *pModule, *pCompObj, *pCompObjInst;
  PyObject *cfunc, *cmeth;

  program = Py_DecodeLocale("exmaple", NULL);
  Py_SetProgramName(program);
  Py_InitializeEx(0);

  sys_path = PySys_GetObject("path");
  module_path = PyUnicode_FromString("/Users/dwalker/ex");
  PyList_Append(sys_path, module_path);
  Py_DECREF(module_path);

  if ((pModule = PyImport_ImportModule("component")) == NULL) {
    printf("No Module\n");
    return -1;
  }

  pCompObj = PyObject_GetAttrString(pModule, "CompObj");
  pCompObjInst = PyObject_CallFunction(pCompObj, NULL);

  cfunc = PyCFunction_New(&override_method, NULL);
  cmeth = PyMethod_New(cfunc, pCompObjInst);

  PyObject_SetAttrString(pCompObjInst, "my_function", cmeth);
  PyObject_CallMethod(pCompObjInst, "test", NULL);

  Py_Finalize();
  PyMem_RawFree(program);

  return 0;
}
  

的CMakeLists.txt

set(SRC_CORE
  example.c
)

add_executable(example ${SRC_CORE})

set_property(TARGET example PROPERTY C_STANDARD 90)

find_package(PythonInterp)
find_package(PythonLibs)
include_directories(${PYTHON_INCLUDE_PATH})
target_link_libraries(example ${PYTHON_LIBRARIES})

所以,在我构建并运行之后,我得到了输出:

Override method 0x0

正在调用override方法,但实例未作为第一个self参数传递。我假设我做错了将方法绑定到实例。对于它的价值,我还尝试了类似的执行路径,方法是通过PyInstanceMethod_New设置方法到pCompObj而不是实例。但无论如何,我都不确定如何正确传递self值。

0 个答案:

没有答案