当我 运行 python3 -i file.py 时到底发生了什么

What exactly happens when I run python3 -i file.py

假设 test.py 有内容

i_am_a_variable = 1
i_am_also_a_var = 2

while True:
    input('> ')

然后,在与 test.py 相同的目录中,我 运行 python3。现在,在 REPL 中,我执行 from test import *。由于 Python 3 REPL 具有自动完成功能,变量实际上也在这个无限 input 循环中自动完成。也就是说,当我 运行

$ python3
>>> from test import *
> i_am_a|

| 代表我的光标)如果我按 Tab,就好像我的光标在行尾 i_am_a,它会自动完成到 i_am_a_variable

现在,如果我 运行 python3 -i test.py,就不会出现这种情况。也就是说,REPL 不会自动完成。那么当我 运行 python3 -i test.py 时到底发生了什么。 test.py 只是 运行 然后 globals 被复制到 REPL 吗?

这是在 macOS 上测试的,以防自动完成在其他 python 发行版上不可用。 谢谢。

在你的代码中执行了一个无限循环,它试图读取标准输入,所以它不会自动完成变量,因为脚本控件在你的代码中读取输入,而不是在 REPL 中。

比方说你 test.py:

i_am_a_variable = 1
i_am_also_a_var = 2

没有循环,REPL 执行代码(python -i test.py)并且自动完成工作,否则它不会因为 REPL 执行循环的 input 语句。如果是正确的,上面你说的通过在 REPL 中导入自动完成的工作将不会工作。

最终方案转载

$ cat test.py
i_am_a_variable = 1
i_am_also_a_var = 2

def Infinite():
    while True:
        input('> ')

$ python3 -i test.py
>>> Infinite()
> i_am_a
i_am_a_variable  i_am_also_a_var  
> i_am_a
i_am_a_variable  i_am_also_a_var  
> i_am_a_variable
> i_am_a
i_am_a_variable  i_am_also_a_var  
> i_am_a
i_am_a_variable  i_am_also_a_var  
> i_am_also_a_var
>

Python 在进入交互模式时初始化自动补全。 (如果您需要详细信息,它会调用 sys.__interactivehook__, and one of the things the default __interactivehook__ does is import rlcompleter 并配置 TAB 以触发完成。)

当您以交互模式启动 Python,然后以交互方式启动 运行 from test import * 时,Python 在进入 input 循环之前打开自动完成。自动完成并不是真的要影响 input,但它确实会影响。

当您 运行 test.pypython3 -i 时,Python 不会进入交互模式。它计划test.py完成时进入交互模式,它计划到运行sys.__interactivehook__并打开在发生这种情况时自动完成,但 input 循环在到达该点之前发生。