use*_*797 10 python exception-handling exception python-3.x
我知道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
Run Code Online (Sandbox Code Playgroud)
当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: ...
Run Code Online (Sandbox Code Playgroud)
这是误导性的,因为原始KeyError根本不是一个错误.我当然可以通过将try/except(EAFP)更改为密钥存在的测试(LBYL)来避免这种情况,但这不是非常Pythonic且不太线程友好(不是上面的线程安全,但是那是除此之外).
期望some_api中的所有代码都将其更改raise X为raise X from None(并且在所有情况下甚至都没有意义)是不合理的.是否有一个干净的解决方案来避免错误消息中不需要的异常链?
(顺便说一下,奖励问题:我在示例中使用的缓存事物基本上等同于cache_dict.setdefault(key, some_api.get_the_value_via_web_service_call(key)),如果只有setdefault的第二个参数可以是一个只能在需要设置值时调用的可调用的.是不是有一个更好/规范的方式吗?)
你有几个选择.
首先,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
Run Code Online (Sandbox Code Playgroud)
对于第二种选择,我假设return value某处隐藏着你没有显示的地方:
try:
return cache_dict[key]
except KeyError:
pass
value = cache_dict[key] = some_api.get_the_value(key)
return value
Run Code Online (Sandbox Code Playgroud)
第三种选择,LBYL:
if key not in cache_dict:
cache_dict[key] = some_api.get_the_value(key)
return cache_dict[key]
Run Code Online (Sandbox Code Playgroud)
对于奖金问题,定义您自己的dict子类,定义__missing__:
class MyCacheDict(dict):
def __missing__(self, key):
value = self[key] = some_api.get_the_value(key)
return value
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
885 次 |
| 最近记录: |