我一直在深入研究源代码,以找出打印结果的时间点。例如:
>>> x = 1
>>> x + 2
3
以上两条语句编译为:
1 0 LOAD_CONST 0 (1)
3 STORE_NAME 0 (x)
6 LOAD_CONST 1 (None)
9 RETURN_VALUE
和
1 0 LOAD_NAME 0 (x)
3 LOAD_CONST 0 (2)
6 BINARY_ADD
7 RETURN_VALUE
第一个语句不打印任何内容,因为 None
是返回值。第二个返回加法的结果。
CPython 的交互式循环调用 PyRun_InteractiveOneObjectEx()
对于每个输入。这gets the AST并调用 run_mod()
到 compile that AST to byte code然后 evaluate the result在虚拟机中。 PyRun_InteractiveOneObjectEx()
获取的返回 Python 对象就是 top of the VM's stack .
到目前为止,所有这些都是我所期望的。但是返回值似乎是thrown away ! REPL 何时打印?
顺便说一句,我可以看到交互模式确实改变了分词器;它invokes PyOS_Readline
使用 sys.ps1
提示符(默认为 ">>> "
)。我在 pythonrun.c
中检查了类似的更改,但没有成功。
最佳答案
您正在展示通过将代码放入函数中生成的字节码的反汇编。这不是交互式代码的编译方式:它使用特殊的“单一”模式(compile()
的第 3 个参数,如果您在 Python 代码中执行相同的操作)。在这种模式下,丢弃每个表达式值的 POP_TOP
操作码变成了 PRINT_EXPR
。 x = 1
什么都不打印的原因是语句在堆栈上没有留下任何需要弹出的东西,所以这个转换不适用。
关于python - CPython 的解释器如何知道打印最后一个表达式的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50374265/