如何禁止显示后续异常的父异常(原因) [英] How to suppress displaying the parent exception (the cause) for subsequent exceptions

查看:79
本文介绍了如何禁止显示后续异常的父异常(原因)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道提高...从无起步,并已阅读。 p>

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



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

  try:
value = cache_dict [key] $除KeyError之外的b $ b:
value = some_api.get_the_value_via_web_service_call(key)
cache_dict [key] =值

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

  Traceback(最近一次通话):
File ...,line ...,in ...
KeyError:'...'

在处理上述异常期间,发生另一个异常:

追溯(最近一次调用为最新):
文件...,行...,在...
some_api.TheInterestingException:...

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



期望some_api中的所有代码将其提高X 更改为<$ c是不合理的$ c>从无起提高X (而且在所有情况下都没有意义)。是否有一个干净的解决方案来避免错误消息中出现不需要的异常链?



(顺便提一下,额外的问题:我在示例中使用的缓存内容基本上是等效的到 cache_dict.setdefault(key,some_api.get_the_value_via_web_service_call(key)),如果只有setdefault的第二个参数是可调用的,则仅在需要将值设为设置。没有更好/规范的方法吗?)

解决方案

您在这里有几种选择。



首先,是orlp建议的更清晰版本:

  try:
值= cache_dict [key]
除外KeyError:
尝试:
值= some_api.get_the_value(key)
除外,例如e:
从无
cache_dict [key] =值

对于第二个选项,我假设存在返回值藏在您未显示的地方:

  try:
返回cache_dict [key]
,除了KeyError:
传递
值= cache_dict [key] = some_api.get_the_value(key)
返回值

第三选项,LBYL:

 如果键不在cache_dict中:
cache_dict [key] = some_api.get_the_value(key)
return cache_dict [key]

对于奖金问题,请定义自己的dict子类,该子类定义 __ missing __

  class MyCacheDict(dict):

def __missing __(self,key):
值= self [key] = some_api.get_the_value(key)
返回值

希望这会有所帮助!


I'm aware of raise ... from None and have read How can I more easily suppress previous exceptions when I raise my own exception in response?.

However, how can I achieve that same effect (of suppressing the "During handling of the above exception, another exception occurred" message) without having control over the code that is executed from the except clause? I thought that sys.exc_clear() could be used for this, but that function doesn't exist in Python 3.

Why am I asking this? I have some simple caching code that looks like (simplified):

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

When there's an exception in the API call, the output will be something like this:

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: ...

This is misleading, as the original KeyError is not really an error at all. I could of course avoid the situation by changing the try/except (EAFP) into a test for the key's presence (LBYL) but that's not very Pythonic and less thread-friendly (not that the above is thread-safe as is, but that's beside the point).

It's unreasonable to expect all code in some_api to change their raise X to raise X from None (and it wouldn't even make sense in all cases). Is there a clean solution to avoid the unwanted exception chain in the error message?

(By the way, bonus question: the cache thing I used in the example is basically equivalent to cache_dict.setdefault(key, some_api.get_the_value_via_web_service_call(key)), if only the second argument to setdefault could be a callable that would only be called when the value needs to be set. Isn't there a better / canonical way to do it?)

解决方案

You have a few options here.

First, a cleaner version of what orlp suggested:

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

For the second option, I'm assuming there's a return value hiding in there somewhere that you're not showing:

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

Third option, LBYL:

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

For the bonus question, define your own dict subclass that defines __missing__:

class MyCacheDict(dict):

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

Hope this helps!

这篇关于如何禁止显示后续异常的父异常(原因)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆