更具描述性的异常的异常设计模式

时间:2016-09-21 01:39:48

标签: python

向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文档和其他常见的包,但没有找到任何结论,至少我可以看到

1 个答案:

答案 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方法。

不要介意我。毕竟,这是一个意见。

相关问题