首页 > 解决方案 > 为什么在 C++ 应用程序中嵌入 python 时继承不能正常工作?

问题描述

在另一个论坛上问过这个问题,但显然这个问题比我想象的更普遍地与 python 相关。奇怪的是,我找不到太多关于这个特定问题的话题。

本质上,我在 base.py 中有一个基类:

class B:
   def __init__(self):
       ...
   def func(self):
       ...

在 child.py 中还有一个子类:

from base import B

class C(B):
   def __init__(self):
       B.__init__(self)
       ...
   def func(self):
       B.func(self)
       ...

如果我创建这些类并纯粹通过 Python 调用它们,那么一切正常。但是,当我尝试通过 C API 执行此操作时,C.func() 无法调用 B.func()。就好像 C.func() 完全忽略了我调用的行B.func(self)

我通过 C API 将 base.py 和 child.py 的内容加载到字符串中来定义这些类。这是通过 Qt 通过 loadFromFile 例程完成的,我相信这可以正常工作。然后我通过一个包装函数调用我为每个类加载的代码PyRun_SimpleString

bool PythonAPI::runCode(const std::string& code)
{
    int ran = PyRun_SimpleString(code.c_str());
    if (ran < 0) {
        printErrors();
        return false;
    }
    return true;
}

所以我的例程实例化一个 Child 实例并运行一个方法,如果它本质上是:

// Initialize interpreter
Py_Initialize();

// Initialize main module
PyObject* mainModule = PyImport_AddModule("__main__");

// Load in code frombase.py and child.py
std::string baseCode = loadFromFile(base.py);
std::string childCode = loadFromFile(child.py);

// Define classes by running code
runCode(baseCode);
runCode(childCode);

// Obtain Child class from python and instantiate
PyObject* cls = PyObject_GetAttrString(mainModule, "Child");
PyObject* instance= PyObject_CallObject(cls, argList);

// Call routine of child instance
PyObject* result = call(instance, func, NULL);

API的工作方式是否有任何奇怪之处可能导致这种情况?我调用类实例方法的例程(减去错误处理)如下所示:

PyObject * PythonAPI::call(PyObject * instance, const std::string& methodName, PyObject * args)
{
    // Obtain pointer to function
    PyObject* method = PyObject_GetAttrString(instance, methodName.c_str());

    // Call function
    PyObject* output = PyObject_CallObject(method, args);

    // Decrement count for function, ignoring if it is null
    Py_XDECREF(method);

    return output;
}

我希望我的应用程序的用户完全通过 Python 进行接口,这就是为什么我想将他们需要的所有东西打包到 B 类中,他们可以从中继承。谢谢!

编辑:经过大量调查,当 B 类和 C 类在同一个文件中时,继承似乎工作得很好。但是,由于项目的限制,我需要将 B 类放在它自己的文件中,所以我不能使用这种解决方法。我不确定为什么这会导致问题。

标签: pythonc++

解决方案


推荐阅读