向Python异常添加额外信息的好方法是什么
例如 我有嵌套字典
d = {'Bob':{'lastname':'Smith'}, 'Sally':{}}
如果我像这样访问字典,我得到了我想要的姓氏
name = 'Bob'
value = 'lastname'
print(d[name][value])
史密斯
如果我尝试访问Sally的姓氏,我也会得到我想要的KeyError
name = 'Sally'
value = 'lastname'
print(d[name][value])
KeyError:'姓氏'
但是我的问题是这个例外是非常不合理的,所以我的代码现在看起来像这个
try:
name = 'Sally'
value = 'lastname'
print(d[name][value])
except KeyError:
raise KeyError("{0} has no {1}".format(name, value))
KeyError:Sally没有姓氏
这给了我一个我正在寻找的描述性错误,但我想知道这个实现是否是pythonic。有没有更好的方式表达这个?我试过查看python文档和其他常见的包,但没有找到任何结论,至少我可以看到
答案 0 :(得分:1)
让我们把它放在那里看看它带给我们的地方。但首先,请看看Jeff Knupp的article关于这个话题。这可能是一个评论,但那里有很多小块。
考虑LBYL(在你跳跃之前看 - 看文章)方法:
if name not in d:
raise KeyError('{0} is not in first level of dict'.format(name))
if value not in d[name]:
raise KeyError('{0} is not in second level of {1}-dict'.format(value, name))
与EAFP相比(更容易请求宽恕而不是许可 - 再次,请参阅文章)方法:
try:
lastnames = d[name]
except KeyError:
raise KeyError('{0} is not in the first level of dict'.format(name))
try:
person = lastnames[value]
except KeyError:
raise KeyError('{0} is not in the second level of {1}-dict'.format(value, name))
现在,考虑一下Zen of Python。在我看来,前一种方法更加美观"并且"更简单。"它也让我觉得更多可读,"虽然这种情况只是微不足道。另一方面,后者更明确"因为它清楚地描述了失败的可能性以及如何处理此类案件。此外,如果您需要扩展错误处理的活动,那么"实用性"不应忽视EAFP方法;如果你需要它,完整try: except: else: finally
条款的力量和便利性不容小觑。话虽如此,我个人倾向于你的try: except:
解决方案。
然而,信任你的直觉可能更重要。如果你尽职尽责地考虑这些事情,即使是在简单的情况下,你也会陷入真正棘手的情况,你真的应该考虑另一种或更多的pythonic方法。
不要介意我。毕竟,这是一个意见。