如何禁止显示后续异常的父异常(原因)
我知道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 X
为raise X from
None
(这在所有情况下都没有意义)是不合理的。是否有一个干净的解决方案来避免错误消息中出现不需要的异常链?
(顺便提一句,额外的问题:cache_dict.setdefault(key,
some_api.get_the_value_via_web_service_call(key))
如果仅将setdefault的第二个参数作为可调用对象(仅当需要设置该值时才调用),则本示例中使用的缓存内容基本上等效于)。更好/规范的方法吗?)
-
您在这里有一些选择。
首先,奥尔普建议的更干净的版本:
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
希望这可以帮助!