【问题标题】:What exactly happens when I run python3 -i file.py当我运行 python3 -i file.py 时到底发生了什么
【发布时间】:2017-06-30 04:46:43
【问题描述】:

假设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 发行版上不可用。 谢谢。

【问题讨论】:

    标签: macos python-3.x read-eval-print-loop


    【解决方案1】:

    当进入交互模式时,Python 会初始化自动完成。 (如果您想了解详细信息,它会调用sys.__interactivehook__,默认__interactivehook__ 所做的一件事是导入rlcompleter 并配置TAB 以触发完成。)

    当您以交互模式启动 Python,然后以交互方式运行 from test import * 时,Python 在遇到 input 循环之前会打开自动完成功能。自动补全并不是真的打算影响input,但它无论如何都会影响。

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

    【讨论】:

    • 那么如果我导入 rlcompleter 我会在我的模块中获得全局/本地的自动完成吗? - 看起来没有:/我真的很好奇如何在我的模块中拥有这种自动完成行为。但这确实回答了我的问题。谢谢。
    • 哈!非常感谢您的回答!在导入sys 之后,我尝试在模块顶部调用sys.__interactivehook__(),现在自动完成功能适用于python3 -i test.py。非常感谢!
    • 为了澄清我上面的评论,我还在调用钩子之前导入了 rlcompleter。
    【解决方案2】:

    在您的代码中执行了一个无限循环,它试图读取标准输入,因此它不会自动完成变量,因为脚本控件在您的代码中读取输入,而不是在 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
    >
    

    【讨论】:

    • 当我使用 from test.py import * 在 REPL 中运行我的代码时,它会执行无限循环,变量 do 会自动完成。我鼓励你测试一下。
    • 没有请检查。
    • Here 是我刚刚制作的屏幕录制的 GIF。请注意,当在 infinite() 中时,自动完成仍然有效。
    • 嗨 Enrico,当无限循环在一个函数内时有效,python3 -i test.py 类似于你的 gif 试试看。
    • 我无法重现... >
    猜你喜欢
    • 1970-01-01
    • 2022-11-27
    • 2011-01-21
    • 2019-10-03
    • 1970-01-01
    • 2011-12-01
    • 2011-09-12
    • 2018-08-25
    • 1970-01-01
    相关资源
    最近更新 更多