文档说调用sys.exit()会引发一个SystemExit异常,该异常可以在外层捕获.我有一种情况,我想明确地,毫无疑问地退出测试用例,但是unittest模块捕获SystemExit并阻止退出.这通常很好,但我试图处理的具体情况是我们的测试框架检测到它被配置为指向非测试数据库的情况.在这种情况下,我想退出并阻止运行任何进一步的测试.当然,由于unittest陷入了SystemExit的困境并继续开心,它正在挫败我.
到目前为止我唯一想到的选择是使用ctypes或者类似的东西来直接调用exit(3),但这对于一些非常简单的东西来说似乎是一个相当糟糕的黑客.
您可以调用os._exit()
直接退出,而不会抛出异常:
import os os._exit(1)
这会绕过所有python关闭逻辑(例如atexit
模块),并且不会运行您在此情况下尝试避免的异常处理逻辑.参数是进程返回的退出代码.
正如杰罗布所说,os._exit(1)
是你的回答.但是,考虑到它绕过所有清理程序,包括finally:
块,关闭文件等,并且应该不惜一切代价避免,我可以提出一种"更安全"的方式来使用它吗?
如果你的问题是SystemExit
在外层被捕(即,单位测试),那么你自己就是外层!总结你的主要代码在try/except块,赶上SystemExit,并调用os._exit那里,并且只有在那里!通过这种方式,您可以sys.exit
正常调用代码中的任何位置,让它冒泡到顶层,优雅地关闭所有文件并运行所有清理,然后调用os._exit.
您甚至可以选择哪些出口是"紧急"出口.下面的代码是这种方法的一个例子:
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!