chr*_*ock 4 python cpython python-internals
我一直在挖掘源代码,以弄清楚打印结果的哪一点.例如:
>>> x = 1
>>> x + 2
3
Run Code Online (Sandbox Code Playgroud)
以上两个陈述编译为:
1 0 LOAD_CONST 0 (1)
3 STORE_NAME 0 (x)
6 LOAD_CONST 1 (None)
9 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
和
1 0 LOAD_NAME 0 (x)
3 LOAD_CONST 0 (2)
6 BINARY_ADD
7 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
第一个语句不打印任何内容,因为None它是返回的值.第二个返回添加的结果.
CPython的交互式循环调用PyRun_InteractiveOneObjectEx()每个输入.这将获取AST并调用run_mod()以将AST编译为字节代码,然后在虚拟机中评估结果.获取的返回Python对象PyRun_InteractiveOneObjectEx()只是VM堆栈的顶部.
到目前为止,所有这些都是我所期待的.但后来返回的值似乎被抛弃了!什么时候由REPL打印?
顺便说一句,我可以看到交互模式确实改变了标记器; 它invokes PyOS_Readline带有sys.ps1提示(">>> "默认情况下).我检查了类似的变化pythonrun.c,但没有运气.
您正在显示通过在函数中使用代码生成的字节码的反汇编.这不是交互式代码的编译方式:它使用特殊的"单一"模式(第三个参数compile(),如果您在Python代码中执行相同的操作).在这种模式下,POP_TOP丢弃每个表达式的值的操作码变为一个PRINT_EXPR.x = 1没有打印的原因是语句不需要在堆栈上留下任何需要弹出的内容,因此这种转换不适用.