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())
可选参数argv
到main()
的原因是,“我们更改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()
的模块,而不是仅使用execfile
或runfile
执行它们吗?这不是我倾向于进行交互式开发的方式,特别是考虑到我需要记住在import foo
和reload(foo)
之间来回切换。
我知道我可以从SystemExit
抓住getopt
或尝试使用一些黑魔法来检测Python是否以交互方式运行,但我认为这些都不是BDFL的意图。
答案 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())