首页 > 解决方案 > 抑制异常但在异常后继续,而不是在抑制后

问题描述

假设以下最小示例:

def external_code():
    for i in range(10):
        if i == 7:
            raise ValueError("I don't like sevens.")
        print(i)

external_code()

通过处理来抑制异常时

try:
    external_code()
except ValueError:
    pass

或通过压制contextlib.suppress()

from contextlib import suppress

with suppress(ValueError):
    external_code()

不会引发异常,但会阻止执行之后的代码,而是在except块中或在抑制之后继续执行。

是否可以抑制异常然后继续使用外部代码,就好像异常甚至不存在一样?在上面的代码示例中,这将导致打印所有 10 个数字,而不是仅打印 0 到 6。

我需要这个,因为外部库(TensorFlow)引发了它不应该引发的异常。与上面的最小示例相关,这意味着我无法编辑函数中的代码,我只能在其调用周围放置代码。我可以在 TensorFlow 中注释掉异常,但是更新 TF 很乏味,并且还会导致异常在其他实际合适的情况下不会发生。

标签: pythonexception

解决方案


作为一种解决方法,您可以随时重新定义该方法:

class SomeTensorFlowClass(object):
    def that_method(self, n=10):
        for i in range(n):
            if i == 7:
                raise ValueError()
            print(i)


stf = SomeTensorFlowClass()

def that_method(n=10):
    self = stf  # for non-static methods
    for i in range(n):
        print(i)

stf.that_method = that_method

这样,您仍然可以“更新”TensorFlow,但您可以在出现这种情况后直接撤消它。

如果您经常切换,您可以添加一个新标志,例如seven_is_ok=False有条件地跳过异常。

如果您想避免复制库源代码,您可以从活动对象中检索它inspect.getsource(stf.that_method)后跟所需的替换和exec("global that_method\n" + adapted_source_code). 请注意,缩进更改和忘记的导入可能仅标志着基于检查的解决方法可能出现的许多问题的开始。

显然,没有一个比修补库更漂亮,但我认为你现在有理由不这样做。


推荐阅读