有没有办法来防止从sys.exit()引发SystemExitexception被捕获?

文档说,调用sys.exit()引发了一个SystemExitexception,可以在外层捕获。 我有一种情况,我想明确地,毫无疑问地从testing用例中退出,但是unittest模块捕获SystemExit并阻止退出。 这通常很好,但是我想要处理的具体情况是我们的testing框架检测到它被configuration为指向非testing数据库。 在这种情况下,我想退出并阻止任何进一步的testing运行。 当然,由于unit testing陷阱SystemExit并继续愉快,它阻碍了我。

我迄今唯一想到的select是使用ctypes或类似的东西直接调用exit(3),但是对于一些应该非常简单的事情来说,这看起来像是一个非常糟糕的黑客攻击。

你可以调用os._exit()直接退出,而不会引发exception:

import os os._exit(1) 

这绕过了所有的pythonclosures逻辑,比如atexit模块,并且不会运行你在这种情况下试图避免的exception处理逻辑。 参数是进程返回的退出代码。

正如os._exit(1)所说, os._exit(1)是你的答案。 但是,考虑到绕过所有的清理程序,包括finally:封锁,closures文件等,真的应该不惜一切代价来避免,我可以提出一个“更安全”的使用方法吗?

如果你的问题是SystemExit在外层(即unittest)被捕获,那么你自己就是外层了! 将你的主代码封装在try / except块中,捕获SystemExit,并在那里调用os._exit, 并且在那里! 通过这种方式,你可以在代码中的任何地方正常调用sys.exit ,让它跳出到顶层,正常closures所有文件并运行所有清理, 然后调用os._exit。

你甚至可以select哪个出口是“紧急”的。 下面的代码是这种方法的一个例子:

 import sys, os EMERGENCY = 255 # can be any number actually try: # wrap your whole code here ... # ... some code if x: sys.exit() # ... some more code if y: sys.exit(EMERGENCY) # use only for emergency exits # ... except SystemExit as e: if e.code != EMERGENCY: raise # normal exit, let unittest catch it else: os._exit(EMERGENCY) # try to stop *that*, sucker!