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



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

将可选参数argv改为main()的原因是,"我们将main()更改为可选参数argv,这允许我们从交互式Python提示符中调用它。"

他这样解释他的代码的最后一行:

现在sys.exit()调用很烦人:当main()调用sys.exit()时,交互式Python解释器将退出!补救的办法是放手main()的返回值指定退出状态。的代码Very end变成

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

main()内部对sys.exit(n)的调用都变成了return n

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

我知道我可以从getopt中捕获SystemExit,或者尝试使用一些黑魔法来检测Python是否正在交互运行,但我认为这两种方法都不是BDFL的意图。

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

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

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

你引用的文章只适用于import .

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

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

相关内容

  • 没有找到相关文章

最新更新