Confusion about sys.exit and SystemExit
我已经阅读了一些关于so的线程和关于SystemExit异常的python文档。这个线程不打算是重复的,因为我在类似的线程中没有找到答案。
调用sys.exit()和提升systemeexit是否都进行清理?我知道sys.exit调用systemeexit,但如果您只提出systemeexit异常,它会为您做任何清理吗?官方的python文档对此不太清楚。我问这个问题的原因是因为我的一个同事认为SystemExit在代码中写得更清楚,而您不需要导入sys模块……但只是引发一个异常,我不确定与调用sys.exit相比是否正在进行任何清理,后者在调用SystemExit之前会从我所知道的内容中进行清理。
- 别忘了对任何有助于你的答案投赞成票。把一个作为答案,让它显得特别好。;)
打电话给sys.exit()只会提高SystemExit。在返回堆栈的过程中,执行清理的是异常处理,因此这两种技术将执行相同的清理。但无论如何,你应该使用sys.exit而不是SystemExit:试图节省一个sys的进口没有意义,这不需要任何成本。调用sys.exit是结束Python进程的常规方法。
也就是说,您确定要在代码中显式地退出进程吗?这使得你的功能很难再利用。通常,当简单地从函数返回时,人们使用sys.exit也可以,因为它是程序的主要功能。
- 这并不完全正确,因为sys.exit()函数根据我所知的自己清理(根据SystemExit的文档,它说sys.exit在执行清理之后调用SystemExit,但没有特别说明何时提升SystemExit本身),但在提升SystemExit woul时必须指定清理代码。D说得通。
- 你错了。sys.exit()函数实际上只执行raise systemeexit。SystemExit的文档没有说明它执行清理。我不知道你读过什么。
根据Atexit的python 2文档,似乎sys.exit和SystemExit都将导致正常的清理。os._exit不会。
更新:让我们详细说明一下答案…
我觉得医生很清楚:
Exit from Python. This is implemented by raising the SystemExit
exception, so cleanup actions specified by finally clauses of try
statements are honored, and it is possible to intercept the exit
attempt at an outer level
号
和
Since exit() ultimately"only" raises an exception, it will only exit
the process when called from the main thread, and the exception is not
intercepted
号
中间缺失的段落与你的问题(大部分)无关。现在,这告诉我们,sys.exit基本上是通过提升SystemExit来实现的,带有一个可选参数,用于关闭虚拟机的代码(指定退出状态代码和消息)。SystemExit只是一个常规的例外,它意味着许多事情:
它可以被抓住。也就是说,您可以编写一个except SystemExit块,防止程序在某一点退出。
它将触发该点堆栈中的所有finally块。您可以使用这些块进行适当的清理。这还包括您可能不知道的try: finally:块,因为上下文处理程序可能在其__exit__方法上有它们。
正如第二段提醒您的,只有程序中的主线程以特殊的方式处理SystemExit。并且异常不会从一个线程传播到另一个线程,因此只有在系统从主线程触发时,才会使系统退出。
总结一下,如果我们简化很多,python的主线程如下所示:
1 2 3 4 5
| try:
run_the_main_script()
except SystemExit as e:
invoke the registered"atexit" functions (in a LIFO way)
check e, set exit status, and quit the program |
请注意,这不会为您做任何特殊的清理。但是,python执行某些清理:调用已注册的清理函数,以受控方式销毁对象(这将刷新缓冲区等)。
- 那么你就没有读足够的书或者是误解了。exit不是sys.exit,exit只能在加载站点模块时在交互shell中使用。
- 如我所说,从sys.exit的文档中。文件很清楚。如果你不识字,那不是我的问题。顺便说一句:您负责清理,通过捕获异常或finally块(也在文档中)
- 没必要那么粗鲁吧?我知道它的堆积如山,但来吧,伙计。是的,我可以阅读,但现在还不清楚sys.exit()函数是否按其编写方式进行了清理,但至少我现在知道了
- 嗯,我想告诉其他人他们不能阅读或误解这个问题不是粗鲁的吧?不管怎样,我读得很清楚,但我会在答案中详细说明…
- 很明显这很粗鲁,因为我想你知道一个30岁的人会读书?说他或她不能做是对他们智力的直接侮辱。如果你想帮助人们回答问题,你应该理解不是每个人都用同样的方式解释同一篇文章,也不是每个人都理解每一件事情,这就是为什么要有这样的论坛。
- 我说的是你对这个答案的第一个评论。读一读,读你刚才说的话,然后三思而后行。如果你想让别人对你好一点,就从你自己好一点开始。