当前位置:  开发笔记 > 编程语言 > 正文

有没有办法防止从sys.exit()引发的SystemExit异常被捕获?

如何解决《有没有办法防止从sys.exit()引发的SystemExit异常被捕获?》经验,为你挑选了2个好方法。

文档说调用sys.exit()会引发一个SystemExit异常,该异常可以在外层捕获.我有一种情况,我想明确地,毫无疑问地退出测试用例,但是unittest模块捕获SystemExit并阻止退出.这通常很好,但我试图处理的具体情况是我们的测试框架检测到它被配置为指向非测试数据库的情况.在这种情况下,我想退出并阻止运行任何进一步的测试.当然,由于unittest陷入了SystemExit的困境并继续开心,它正在挫败我.

到目前为止我唯一想到的选择是使用ctypes或者类似的东西来直接调用exit(3),但这对于一些非常简单的东西来说似乎是一个相当糟糕的黑客.



1> Jerub..:

您可以调用os._exit()直接退出,而不会抛出异常:

import os
os._exit(1)

这会绕过所有python关闭逻辑(例如atexit模块),并且不会运行您在此情况下尝试避免的异常处理逻辑.参数是进程返回的退出代码.



2> MestreLion..:

正如杰罗布所说,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!


我需要检查的一种情况是代码是否为0,这表明我们正在尝试正常退出而不会出现错误/崩溃。当通过-h arg并且不希望将SystemExit视为异常时使用OptionParser时,这很有用。因此,非常感谢,您帮助我验证了如何通过异常访问退出代码。
推荐阅读
mobiledu2402852413
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有