我有一个C++/Qt应用程序,其中我正在主应用程序的进程中运行Python解释器会话.我构建了一个作为QPlainTextEdit小部件的"Python控制台",它使用Python C API处理解释器的输入和输出.所有这一切的重点是,Python将可以直接访问我在主应用程序中保存的数据.一切都很好,只是我希望能够结束当前的解释器会话并在不退出主应用程序的情况下重新启动它.

目前,我正在try 显而易见的方法:

Py_Initialize();
// Run the main session...
Py_FinalizeEx();

// Restart the session
Py_Initialize();

从阅读其他帖子和Python的文档来看,由于内存泄漏,在最终确定解释器后重新加载某些模块可能会出现问题.在我的 case 中似乎是正确的:重新导入某些模块(例如"numpy"),但其他模块(例如"sys")不会触发异常并失败.

是否有一个好的变通策略可以在没有这些问题的情况下重新启动解释器?例如,如果我产生一个子解释器,那么最终确定它并重新启动新的子解释器是否会遇到与我遇到的相同的问题?我试图避免的替代方案是在进程外运行Python,我认为这将允许我通过基本上杀死进程并启动新进程来重新启动.任何策略建议都将不胜感激.

推荐答案

Py_FinalizeEx documentation:

Bugs and caveats:模块和模块中对象的 destruct 是 以随机顺序完成;这可能会导致析构函数(del()方法) 当它们依赖于其他对象(甚至函数)或模块时就会失败. Python加载的动态加载扩展模块不是 卸下.Python解释器分配的少量内存 可能无法释放(如果发现泄漏,请报告).记忆束缚 对象之间的循环引用中的up不会被释放.一些存储器 扩展模块分配的可能不会被释放.一些扩展可能 如果初始化 routine 被调用的次数超过 一次;如果应用程序调用Py_Initialize()并且 Py_FinalizeEx()不止一次.

特别注意:

如果某些扩展may not work properly的初始化 routine 被调用超过 一次; this can happen if an application calls Py_Initialize() and Py_FinalizeEx() more than once.

(emphasys is mine)

很明显,正如您所try 的那样,设计does not support finalization and reinitialization.

因此,建议您初始化Python引擎一次(当您的流程启动时或第一次需要它时),并仅在退出时(或者至少当您确定不再需要它时)才最终确定它.

即使您找到了一些适用于特定场景的解决方案,鉴于上述信息,我也认为这不是一个好主意.

Note:
If you have some requirement that mandates creating a new Python envirionment for each session or operation, the best approach is to run Python as an external process.

Python相关问答推荐

是否有使用纯霍夫曼编码的现代图像格式?

判断两极中N(N 2)列水平是否相等

CustomTKinter-向表单添加额外的输入字段

单击Python中的复选框后抓取数据

在两极中实施频率编码

如何使用PyTest根据self 模拟具有副作用的属性

如何让pyparparsing匹配1天或2天,但1天和2天失败?

如何将我的位置与光强度数据匹配到折射图案曲线中?

查找下一个值=实际值加上使用极点的50%

剧作家Python:expect(locator).to_be_visible()vs locator.wait_for()

Matlab中是否有Python的f-字符串等效物

重新匹配{ }中包含的文本,其中文本可能包含{{var}

Pytest两个具有无限循环和await命令的Deliverc函数

删除任何仅包含字符(或不包含其他数字值的邮政编码)的观察

如何避免Chained when/then分配中的Mypy不兼容类型警告?

删除字符串中第一次出现单词后的所有内容

我如何使法国在 map 中完全透明的代码?

pandas:排序多级列

在Django admin中自动完成相关字段筛选

SQLAlchemy bindparam在mssql上失败(但在mysql上工作)