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

Python 如何禁止显示后续异常的父异常(原因),python,exception,python-3.x,exception-handling,Python,Exception,Python 3.x,Exception Handling,我知道,raise。。。从无开始并已阅读 但是,在不控制从except子句执行的代码的情况下,如何实现相同的效果(抑制“在处理上述异常期间,发生了另一个异常”消息)?我认为可以使用sys.exc\u clear()来实现这一点,但Python 3中不存在该函数 我为什么要问这个?我有一些简单的缓存代码,如下所示(简化): 当API调用中出现异常时,输出如下: Traceback (most recent call last): File ..., line ..., in ... KeyEr

我知道,
raise。。。从无开始
并已阅读

但是,在不控制从except子句执行的代码的情况下,如何实现相同的效果(抑制“在处理上述异常期间,发生了另一个异常”消息)?我认为可以使用
sys.exc\u clear()
来实现这一点,但Python 3中不存在该函数

我为什么要问这个?我有一些简单的缓存代码,如下所示(简化):

当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: ...
这是一种误导,因为最初的keyrerror根本不是一个真正的错误。当然,我可以通过将try/except(EAFP)更改为密钥存在性测试(LBYL)来避免这种情况,但这不是非常Pythonic的,也不是线程友好的(并不是说上面的内容是线程安全的,但这不是重点)

期望某些api中的所有代码将它们的
raisex
从None更改为
raisex是不合理的(甚至在所有情况下都没有意义)。是否有一个干净的解决方案来避免错误消息中不需要的异常链


(顺便提一下,还有一个问题:我在示例中使用的缓存基本上等同于
cache\u dict.setdefault(key,some\u api.get\u value\u通过web\u service\u调用(key))
,如果setdefault的第二个参数只能是一个可调用的参数,那么只有在需要设置值时才会调用它。难道没有更好的/规范的方法吗?

您可以自己尝试抑制上下文:

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

    cache_dict[key] = value

你有几个选择

首先,orlp建议的更干净版本:

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
对于第二个选项,我假设有一个
返回值
隐藏在您没有显示的地方:

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子类,该子类定义
\uuuuu missing\uuuu

class MyCacheDict(dict):

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

希望这有帮助

defaultdict
修改应该对您有用:谢谢。您的第一个建议有一个问题:1)它可能会抑制比它应该抑制的更多的内容(可能在跟踪库中列出的API代码中有一个有用的上下文),2)它会掩盖异常的来源(用户现在看到的不是API中的模块作为回溯的最后一行,而是我的代码,API将是最后一行),这是我迄今为止所看到的所有解决方案中的首选方案。你关于抑制可能有用的上下文的观点肯定是有效的,因此,该建议可能不应该使用。然而,你关于掩盖来源的观点是无效的:完全相同的例外,追溯和所有,被重新提出,只是没有上下文。我我个人更愿意使用带有
\uuuu missing\uuu
的dict子类或LBYL选项。
class MyCacheDict(dict):

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