【问题标题】:PyImport_Import failing when submodules are imported in a python module在 python 模块中导入子模块时 PyImport_Import 失败
【发布时间】:2020-05-21 20:07:05
【问题描述】:

我有一个这样的 cpp 代码:

void callPython() {
    Py_Initialize();    
    PyObject* sysPath = PySys_GetObject("path");
    PyList_Append(sysPath, PyUnicode_FromString("/jarvis_repo/src/cpp/packages/jarvis/nlp/"));
    // Load the module
    PyObject *pName = PyUnicode_FromString("my_mod");
    PyObject *pModule = PyImport_Import(pName);
    if (pModule != NULL) {
        std::cout << "Python module found\n";       

        PyObject* pFunc = PyObject_GetAttrString(pModule, "my_func");
        if(pFunc != NULL){
            PyObject_CallObject(pFunc, NULL);
        } else {
            std::cout << "Couldn't find func\n";
        }
    }
    else {
        PyErr_Print();
        std::cout << "Python Module not found\n";
}     
    Py_Finalize();
}

我在同一目录/jarvis_repo/src/cpp/packages/jarvis/nlp/也有两个文件my_mod.py和test.py,如下:

my_mod.py

from test import coreDM
def my_func():
    print("my_func() got called")
    coreDM()

test.py

class coreDM():
    def __init__(self):
        print("Initialized test")

    def print_message():
        print("Hello from coreDM")

from test import coreDMcoreDM()my_mod.py 中省略时, PyImport_Import 工作正常并打印 my_func() got called 否则返回 NULL。 知道为什么会发生这种情况吗? 提前致谢!

错误信息:

ImportError: cannot import name 'coreDM'
Python Module not found

【问题讨论】:

  • 您是否尝试过显示异常消息? NULL 表示错误,该消息可能会告诉您哪里出了问题。很可能是 coreDM 有问题,这会在导入时引发异常(通常是 SyntaxError 或对 dmEngine 的递归依赖),但如果没有 minimal reproducible example,我们就不能说太多了。
  • 添加了最小可重现示例。 BTW 如何显示来自PyImport_Import 的异常消息?
  • 我想出了如何打印错误信息。我用PyErr_Print();。使用收到的错误消息更新问题。
  • test 始终是模块的一个可疑名称,因为 CPython 测试套件称为 test
  • 尝试将 test.py 更改为其他名称。还是不行。

标签: python c++ python-c-api python-embedding


【解决方案1】:

使用PyList_Insert 代替PyList_Append 从您想要的位置导入测试。

正如@DavidW 提到的,核心库中有一个可导入的模块,名为test

改变

PyList_Append(sysPath, PyUnicode_FromString("/jarvis_repo/src/cpp/packages/jarvis/nlp/"));

PyList_Insert(sysPath, 0, PyUnicode_FromString("/jarvis_repo/src/cpp/packages/jarvis/nlp/"));

所以test 模块首先在 /jarvis_repo/src/cpp/packages/jarvis/nlp/ 中找到,而不是在核心库中。

注意:你应该改名为test

【讨论】:

    猜你喜欢
    • 2013-12-03
    • 2017-01-25
    • 2019-04-28
    • 1970-01-01
    • 2021-10-13
    • 2017-12-26
    • 1970-01-01
    • 2011-12-25
    相关资源
    最近更新 更多