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

时间:2014-05-17 17:30:56

标签: python main exit

BDFL于2003年发布an article about how to write a Python main function。他的例子是:

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())

可选参数argvmain()的原因是,“我们更改main()以获取可选的argv参数,这允许我们从交互式中调用它Python提示。“

他解释了他的代码的最后一行:

  

现在sys.exit()来电很烦人:当main()拨打sys.exit()时,   您的交互式Python解释器将退出!补救措施是让   main()的返回值指定退出状态。因此,代码在   非常结束

if __name__ == "__main__":
    sys.exit(main())
     

sys.exit(n)main()的来电全部变为return n

然而,当我在Spyder控制台中运行Guido的代码时,它会杀死解释器。我在这里错过了什么?我只想import具有此类型main()的模块,而不是仅使用execfilerunfile执行它们吗?这不是我倾向于进行交互式开发的方式,特别是考虑到我需要记住在import fooreload(foo)之间来回切换。

我知道我可以从SystemExit抓住getopt或尝试使用一些黑魔法来检测Python是否以交互方式运行,但我认为这些都不是BDFL的意图。

2 个答案:

答案 0 :(得分:9)

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

execfile('test.py', {'__name__': 'test'})

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

您引用的文章仅适用于import

答案 1 :(得分:0)

我在问题中简要提到的另一种处理它的方法是尝试检测你是否处于交互式环境中。我不相信这可以移植,但这是为了防止它对某人有帮助:

if __name__ == "__main__":
    if 'PYTHONSTARTUP' in os.environ:
        try:
            main() # Or whatever you want to do here
        except SystemExit as se:
            logging.exception("")
    else:
        sys.exit(main())