1

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)

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

4

3 回答 3

6

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

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

于 2012-09-17T19:13:49.957 回答
3

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

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

更新 2:注意 @sapht 建议使用异常来协调退出。这是一个很好的建议,如果你真的想做一个非本地出口。比设置全局要好得多。

于 2012-09-17T19:09:33.570 回答
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实际上并没有尽快退出解释器(它抛出并捕获异常),所以这是一种错误的安全感。但是你仍然经常看到它。

于 2012-09-17T19:52:10.723 回答