【问题标题】:Printing a variable in an embedded Python interpreter在嵌入式 Python 解释器中打印变量
【发布时间】:2012-03-02 22:37:17
【问题描述】:

我编写了一个嵌入 Python 的小型 C 程序。我使用 Py_Initialize() 和 Py_Finalize() 正确设置它,并且能够使用 PyRun_SimpleString 或 PyRun_SimpleFile 运行脚本。但是,我不知道在打印变量时如何模仿 Python 自己的解释器的行为。

具体来说:

a = (1, 2, 3)
print a

对我来说很好:它打印出 (1, 2, 3)

但是:

a = (1, 2, 3)
a

什么都不打印。在 Python 自己的解释器中,这也会打印出 (1, 2, 3)。如何让我的代码执行用户期望的操作并打印出值?

提前致谢!

【问题讨论】:

  • 你需要模拟解释器。只需逐行评估输入并print 结果。

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


【解决方案1】:

要运行解释器交互循环,您应该使用函数PyRun_InteractiveLoop()。否则,您的代码将表现得好像它是在 Python 脚本文件中编写的,而不是以交互方式输入的。

编辑:这是一个简单的交互式解释器的完整代码:

#include <Python.h>

int main()
{
    Py_Initialize();
    PyRun_InteractiveLoop(stdin, "<stdin>");
    Py_Finalize();
}

Edit2:在 GUI 中实现一个完整的交互式解释器是一个项目。可能最简单的方法是编写一个连接到伪终端设备的基本终端仿真器,并在该设备上使用上述代码。这将自动使所有细节正确。

如果您的目标不是一个成熟的交互式编辑器,一个选项可能是使用PyRun_String()Py_single_input 作为开始标记。这将允许您像在交互式解释器中一样运行一些 Python 代码,并且如果该代码恰好是一个不计算为 None 的表达式,则将其值的表示打印 - 当然是标准输出。这是一些示例代码(为简单起见,没有错误检查):

#include <Python.h>

int main()
{
    PyObject *main, *d;
    Py_Initialize();
    main = PyImport_AddModule("__main__");
    d = PyModule_GetDict(main);
    PyRun_String("a = (1, 2, 3)", Py_single_input, d, d);
    PyRun_String("a", Py_single_input, d, d);
    Py_Finalize();
}

这将打印(1, 2, 3)

还有很多问题:

  • 没有错误处理和回溯打印。
  • 对于交互式解释器中的块命令,没有“增量输入”。输入需要完整。
  • 输出到标准输出。
  • 如果给出多行输入,则不打印任何内容。

要真正复制交互式解释器的行为并不容易。这就是为什么我最初的建议是在你的 GUI 中编写一个基本的终端模拟器,这应该不会太难——或者甚至可能有一个可用的。

【讨论】:

  • 是的,我试过这个,但它似乎需要交互式输入——除非我做错了什么。我尝试的是: FILE *myfile = fopen("example.py","r+"); PyRun_InteractiveLoop(myfile, "example.py"); fclose(myfile);
  • @FizzBu​​zz:所以您想从文件中读取命令,但希望它们表现得好像它们是交互式输入的一样?你声称这是你的用户所期望的?我确定我在这里遗漏了一些东西。
  • @FizzBu​​zz:请注意,您传递给PyRun_InteractiveLoop() 的文件必须“与交互式设备相关联”,如链接文档所述。
  • 你是对的;我只是不清楚-对不起!我最初的测试应用程序在终端上;将 Python 指向标准输入并让它工作是微不足道的。但是,我想把它带入一个 GUI,它应该以相同的方式对用户表现,但不是那么容易连接。我想从某个地方(不是标准输入;一个 GUI 文本框)读取用户输入,并让它以与命令行解释器相同的方式执行。最初我使用 PyRun_SimpleString() 发送每一行,但我也尝试将命令写入文件并从那里运行。我希望这更清楚;感谢您的耐心等待!
  • @FizzBu​​zz:是的,这真的很清楚!谢谢,我会更新我的答案。你在哪个平台上?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-12
  • 2023-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-19
相关资源
最近更新 更多