嵌入式 Python3 在导入本地模块时引发异常

Posted

技术标签:

【中文标题】嵌入式 Python3 在导入本地模块时引发异常【英文标题】:Embedded Python3 raise an exception when importing a local module 【发布时间】:2016-04-24 22:21:37 【问题描述】:

我正在尝试将 Pyhton3 程序嵌入到 C++ 程序中。在遵循几个教程和博客文章后,我得到以下代码,但失败:

Py_SetProgramName(_program_name);
Py_Initialize();

PyObject* main = PyImport_AddModule("__main__");
PyObject* globalDictionary = PyModule_GetDict(main);
PyObject* localDictionary = PyDict_New();
//create the dictionaries as shown above
PyObject* pythonpath = PySys_GetObject("path");
if (PyList_Append(pythonpath, PyBytes_FromString("/path/to/my/modules")) ==  -1)

  std::cerr << "Failed to append to python path" << std::endl;
  PyErr_Print();

const char* pythonScript = ""
"import sys\n"
"print('Hello')\n"
"import options\n"
"print('World')\n"
"";
PyObject* returnValue = PyRun_String(pythonScript, Py_file_input, globalDictionary, localDictionary);
if (!returnValue)

  std::cerr << "python raised an exception" << std::endl;
  PyErr_Print();
  return 1;

结果如下:

Hello
python raised an exception
Traceback (most recent call last):
  File "<string>", line 5, in <module>
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load
  File "<frozen importlib._bootstrap>", line 2222, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 2164, in _find_spec
  File "<frozen importlib._bootstrap>", line 1940, in find_spec
  File "<frozen importlib._bootstrap>", line 1914, in _get_spec
  File "<frozen importlib._bootstrap>", line 2049, in find_spec
  File "<frozen importlib._bootstrap>", line 53, in _path_join
  File "<frozen importlib._bootstrap>", line 53, in <listcomp>
TypeError: 'str' does not support the buffer interface

因此,导入 sys 有效,但导入我自己的模块失败,而将路径添加到我的模块似乎有效。

有什么想法吗?

【问题讨论】:

【参考方案1】:

PyBytes_FromString 替换为PyUnicode_DecodeFSDefault 使导入工作正常进行。不过我不明白为什么。

【讨论】:

以上是关于嵌入式 Python3 在导入本地模块时引发异常的主要内容,如果未能解决你的问题,请参考以下文章

python3 异常处理

嵌入式 Python 加载模块但不加载该模块的内部导入语句

在嵌入式 Python 中禁用内置模块导入

当 Python 3 中已经存在异常时引发异常

使用不同的C++支持库的模块混合开发时,引发异常展开不正常,抛异常竟引出一个SIGSEGV

使用不同的类型和消息重新引发异常,保留现有信息