如何在交互模式下跳过`if __name__ == "__main__"`?

5

假设有一个简单的脚本:

#!/usr/bin/env python3

if __name__ == "__main__":
    print("Hello World")

如何在交互式解释器中加载代码但不执行if __name__ == "__main__":块?默认情况下会执行该块:

$ python3 -i simple-script.py
Hello World
>>> █

“将其加载到交互式解释器中”是什么意思?就像你可以导入它一样。 - BrenBarn
我想直接从命令行将脚本加载到解释器中,而不必在PYTHONPATH上瞎折腾,并且避免文件名包含“-”时带来的麻烦。python3 -i simple-script.py正是这样做的,除了__name__ == "__main__"问题。 - Grumbel
5个回答

10

不要将其作为参数传递,而应该将其导入解释器。

$ python3
>>> import simple_script
>>>

6
"from simple_script import *" 可能更好,因为它更接近于 "-i" 的功能。 - nneonneo
更好的方法是:python -i -c "from vidthumbzip import *",这样可以避免在交互式Python shell中输入。但仍然希望使用文件名而不是模块名。 - Grumbel
@nneonneo,虽然这是正确的,但应该在此处放置一些警告。如果 OP 通过导入所有内容覆盖(有意或无意地)任何函数,则可能会导致不良结果。保持 simple_script 的命名空间是更可取的。 - James Mertz
这个解决方案的问题在于它只适用于文件名是有效模块名称的情况,而当涉及到脚本时通常并非如此(即/usr/bin/awesome-script)。 - Grumbel

6

从脚本内部,您可以通过检查sys.flags.inspect标志来检测是否传递了-i

import sys

if __name__ == '__main__':
    # code run with or without -i
    if not sys.flags.inspect:
        # code not run with -i

2
除了 @DanielRoseman 的 答案,如果您使用 IPython 或 jupyter 解释器,您可以使用 -n 标志与 %run 魔术命令

-n __name__ 不会被设置为‘__main__’,而是设置为运行文件的名称(不带扩展名),这与 Python 在导入时所做的相同。这使得可以运行脚本并重新加载其中的定义,而无需调用由 if __name__ == "__main__" 保护的代码。


0

由于看起来 Python 没有处理这种情况的方法,所以我编写了一个小脚本 ipy 来完成任务:

使用方法:

$ ipy simple-script.py
>>>

0
解决这个问题最干净的方法是以这样的方式编写项目,即没有if __name__ == "__main__":块,而只有一个带有main()函数的模块,并使用setuptools的entry_points功能从模块生成可执行脚本。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接