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