使用execfile时如何防止运行__main__保护?

kuz*_*roo 4 python program-entry-point exit

BDFL在2003年发布了一篇关于如何编写Python主函数的文章.他的榜样是这样的:

import sys
import getopt

class Usage(Exception):
    def __init__(self, msg):
        self.msg = msg

def main(argv=None):
    if argv is None:
        argv = sys.argv
    try:
        try:
            opts, args = getopt.getopt(argv[1:], "h", ["help"])
        except getopt.error, msg:
             raise Usage(msg)
        # more code, unchanged
    except Usage, err:
        print >>sys.stderr, err.msg
        print >>sys.stderr, "for help use --help"
        return 2

if __name__ == "__main__":
    sys.exit(main())
Run Code Online (Sandbox Code Playgroud)

究其原因,可选的参数argvmain()就是,"我们改变main()采取一个可选的argv参数,它使我们能够从交互式Python提示符调用它."

他解释了他的代码的最后一行,如下所示:

现在sys.exit()调用很烦人:main()调用时sys.exit(),您的交互式Python解释器将退出!补救措施是让 main()返回值指定退出状态.因此,最终的代码变成了

if __name__ == "__main__":
    sys.exit(main())
Run Code Online (Sandbox Code Playgroud)

并且对sys.exit(n)内部的呼唤main()都成了return n.

但是,当我在Spyder控制台中运行Guido的代码时,它会杀死解释器.我在这里错过了什么?我的意图是只有import具有此类型的模块,而main()不仅仅是用execfile或执行它们runfile?这不是我倾向于做互动发展,特别是考虑到它需要我记得之间来回切换import fooreload(foo).

我知道我能赶上SystemExitgetopt或尝试使用一些魔法来检测是否Python的交互方式运行,但我认为这些都不是的BDFL的意图.

Mar*_*ers 9

您的选择是不使用execfile或传递不同的__name__值作为全局:

execfile('test.py', {'__name__': 'test'})
Run Code Online (Sandbox Code Playgroud)

默认设置是将文件作为脚本运行,这意味着将__name__其设置为__main__.

您引用的文章仅适用于import.