模拟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的“返回值”行为的主要内容,如果未能解决你的问题,请参考以下文章
使用 python 的模拟 patch.object 更改在另一个方法中调用的方法的返回值