如何禁止显示后续异常的父异常(原因)

发布于 2021-01-29 16:00:50

我知道raise ... from None并已阅读当我提出自己的异常作为响应时,如何更轻松地抑制以前的异常?

但是,如何在不控制从except子句执行的代码的情况下实现相同的效果(抑制“在处理以上异常期间,发生另一个异常”消息)?我以为sys.exc_clear()可以用于此目的,但是该功能在Python
3中不存在。

我为什么要问这个?我有一些简单的缓存代码,看起来像(简化):

try:
    value = cache_dict[key]
except KeyError:
    value = some_api.get_the_value_via_web_service_call(key)
    cache_dict[key] = value

当API调用中出现异常时,输出将如下所示:

Traceback (most recent call last):
  File ..., line ..., in ...
KeyError: '...'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ..., line ..., in ...
some_api.TheInterestingException: ...

这是一种误导,因为原始的KeyError根本不是错误。我当然可以通过将try /
except(EAFP)更改为测试密钥是否存在(LBYL)的方法来避免这种情况,但这不是Python风格,也不是线程友好的(不是上面的代码本身就是线程安全的,但是除此之外)。

期望some_api中的所有代码将其更改raise Xraise X from None(这在所有情况下都没有意义)是不合理的。是否有一个干净的解决方案来避免错误消息中出现不需要的异常链?

(顺便提一句,额外的问题:cache_dict.setdefault(key, some_api.get_the_value_via_web_service_call(key))如果仅将setdefault的第二个参数作为可调用对象(仅当需要设置该值时才调用),则本示例中使用的缓存内容基本上等效于)。更好/规范的方法吗?)

关注者
0
被浏览
48
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您在这里有一些选择。

    首先,奥尔普建议的更干净的版本:

    try:
        value = cache_dict[key]
    except KeyError:
        try:
            value = some_api.get_the_value(key)
        except Exception as e:
            raise e from None
        cache_dict[key] = value
    

    对于第二个选项,我假设return value您没有显示的地方藏有一个隐藏物:

    try:
        return cache_dict[key]
    except KeyError:
        pass
    value = cache_dict[key] = some_api.get_the_value(key)
    return value
    

    第三种选择,LBYL:

    if key not in cache_dict:
        cache_dict[key] = some_api.get_the_value(key)
    return cache_dict[key]
    

    对于奖励问题,请定义自己的dict子类,该子类定义__missing__

    class MyCacheDict(dict):
    
        def __missing__(self, key):
            value = self[key] = some_api.get_the_value(key)
            return value
    

    希望这可以帮助!



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看