从函数中退出()是不好的形式吗?

时间:2012-09-17 19:06:37

标签: python function

来自函数内的exit()是不是很糟糕?

def respond_OK():
    sys.stdout.write('action=OK\n\n')
    sys.stdout.flush() # redundant when followed by exit()
    sys.exit(0)

而不是从exit()名称空间设置退出代码和__main__

def respond_OK():
    global exit_status
    sys.stdout.write('action=OK\n\n')
    sys.stdout.flush()
    exit_status = 0

sys.exit(exit_status)

从功能的角度来看差异可以忽略不计,只是想知道对形式的共识是什么。如果您在其他人的代码中找到了先前的代码,您会看两次吗?

3 个答案:

答案 0 :(得分:6)

我更希望看到从主入口点引发并处理的异常,其类型被转换为退出代码。在python中子类化异常非常简单,这几乎很有趣。

正如本回答中所述:使用sys.exit也意味着终止点需要知道实际的状态代码,而不是遇到的错误。当然,这可以通过一组常数来解决。但是,使用异常还有其他优点:如果一个方法失败,您可以尝试另一个方法而无需重新输入,或打印一些事后调试信息。

答案 1 :(得分:3)

它在功能方面没有任何区别,但它可能会使您的代码更难以遵循,除非您采取适当的步骤,例如评论来自主命名空间的每个调用,这可能导致退出。

更新:注意@ mgilson的答案是捕获异常的效果[可以捕获system.exit引发的异常,从而防止退出]。你可以让你的代码更加混乱。

更新2:注意@ sapht建议使用异常来编排出口。如果您真的想要进行非本地退出,这是一个很好的建议。比设定全球更好。

答案 2 :(得分:3)

在某些情况下,这是合理惯用的。

如果用户给你错误的命令行参数,而不是:

def usage(arg0):
  print ... % (arg0,)
  return 2

if __name__ == '__main__':
  if ...:
    sys.exit(usage(sys.argv[0]))

你经常看到这个:

def usage():
  print ... % (sys.argv[0],)
  sys.exit(2)

if __name__ == '__main__':
  if ...:
    usage()

我能想到的唯一其他常见情况是初始化某些库(通过ctypes或低级C扩展模块)意外失败并使您处于无法推理的状态,因此您只想获得尽快退出(例如,减少分类或打印垃圾的机会)例如:

if libfoo.initialize() != 0:
  sys.exit(1)

有些人可能会反对这一点,因为sys.exit实际上并没有尽快摆脱解释器(它抛出并捕获异常),所以这是一种虚假的安全感。但你仍然经常看到它。