模拟Python shell的“返回值”行为

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模拟Python shell的“返回值”行为相关的知识,希望对你有一定的参考价值。

假设我有一个要评估的Python字符串的JSON列表。例如,也许我正在构建客户端服务器Python GUI。

关于常规Python解释器的方便之处在于,它显示了每一行的“伪返回值”,如下所示:

 $ python3 -c "import code; code.interact()"
 Python 3.7.7 (default, Mar 10 2020, 15:43:03) 
 (InteractiveConsole)
 >>> import os; os.curdir
 '.'

我不必要求打印出'。'。就做到了。

在幕后,可以看到这是通过exec()函数实现的:

https://github.com/python/cpython/blob/800a35c623bbcdb5793c7d7a4974524286311479/Lib/code.py#L90

    try:
        exec(code, self.locals)
    except SystemExit:
        raise
    except:
        self.showtraceback()

奇怪的是,那里没有显式的指令来输出exec()的结果。但是我们可以看到它确实输出了它。

我们可以看到这种行为是非常特定于上下文的,如下所示:

$ echo "5" | python3 -c "import code; code.interact()"
Python 3.7.7 (default, Mar 10 2020, 15:43:03) 
(InteractiveConsole)
>>> 5
>>> 
now exiting InteractiveConsole...
enter code here

我假设如果我深入研究C代码,我将看到它正在查询其上下文以查看是否输出该值。但这并不能回答我的主要问题,即如何在任意上下文中模拟此行为。

无论字符串是表示表达式还是语句,如何从Python字符串执行并获取“伪返回值”?

答案

Python编译器具有flag to keep track of whether Python is being run in interactive mode

如果设置了此标志,则当编译器访问AST中的语句节点时,它是emits an extra PRINT_EXPR opcode

解释器PRINT_EXPR,是将表达式的结果从堆栈中弹出并将其作为参数传递给executes PRINT_EXPR。 Displayhook将此值的PRINT_EXPR打印到stdout,除非该值为None。还将值分配给sys.displayhook

((我想将命令传递给Python时行为不同的原因是,它不在交互模式下。)

只要您以交互方式运行Python,您就可以在使用sys.displayhook内置代码运行代码后读取repr内置值。

以上是关于模拟Python shell的“返回值”行为的主要内容,如果未能解决你的问题,请参考以下文章

shell脚本中执行python脚本并接收其返回值的例子

从子shell返回值并输出到局部变量

使用 python 的模拟 patch.object 更改在另一个方法中调用的方法的返回值

PHP调用shell命令,怎么实现,我为啥shell_exec的返回值总是null呢

mock

Python模拟数据工具哪些比较好用