如果在IPython中 __name__ == '__main__'

27
我有一些Python脚本,使用if __name__ == '__main__'的技巧,使得某些代码只在脚本作为程序运行时才运行,而不是在交互式解释器中加载时运行。但是,当我使用%edit命令从IPython编辑这些脚本时,IPython似乎将__name__设置为'__main__',因此每次退出编辑会话时都会运行该代码。是否有好的方法可以让这段代码在从IPython编辑模块时不运行?
4个回答

27

当在Emacs中工作时(我假设这与使用%edit得到的效果类似),我通常使用以下技巧:

if __name__ == '__main__' and '__file__' in globals():
    # do what you need

由于明显的原因,__file__ 只对 import 的模块定义,而不是交互式 shell。


1
对于那些不知道Jupyter笔记本是从IPython笔记本开发而来的人,我要指出第二部分的添加可以在Jupyter笔记本中起作用,这样当将相关代码块粘贴到笔记本的单元格中时,该代码块就不会被运行。此外,那些考虑这个方法的人可能会对这里提供的方法感兴趣。 - Wayne

11

听起来你可能只需要使用-x开关:

In [1]: %edit
IPython will make a temporary file named: /tmp/ipython_edit_J8j9Wl.py
Editing... done. Executing edited code...
Name is main -- executing
Out[1]: "if __name__ == '__main__':\n    print 'Name is main -- executing'\n"

In [2]: %edit -x /tmp/ipython_edit_J8j9Wl
Editing...

当你调用%edit -x时,退出编辑器后不会执行代码。


那个 -x 开关至关重要。 - Paul H
谢谢,这很有用,但它并不完全符合我的要求,因为我想让IPython加载模块中定义的函数/类,只是不运行与模块相关的测试代码。 - ajd
没问题。我想你可能需要这样的澄清。考虑到这一点,我个人建议采纳@ffriend的答案。 - Two-Bit Alchemist

8

IPython会将函数get_ipython()添加到全局可用变量中。因此,您可以通过测试globals()中是否存在该函数来进行决策:

if __name__ == '__main__' and "get_ipython" not in dir():
    print "I'm not loaded with IPython"

上述代码只是测试是否存在名为get_ipython的全局变量。如果还要测试该变量是否可调用,可以执行以下操作:
if __name__ == '__main__' and not callable(globals().get("get_ipython", None)):
    print "I'm not loaded with IPython"

2

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