在Python中避免输入和无用的错误消息



考虑下面的代码,它嵌入在某个模块的深处(foo和bar是dicts)。

vals = [foo[key] for key in bar.keys()]

如果由于某种原因bar包含foo不包含的键,这将导致KeyError。假设用户与此模块交互的方式与foo或bar无关,但传递了模块作者没有预见到的导致此错误引发的某种参数。作者没有检查输入并禁止输入的这种类型/值,而是做了python式的事情,让这个错误被抛出。

我的问题是:Python的duck类型似乎会导致无益的错误消息,就像上面这个假设的情况一样。是否有一种方法来编写代码,使其抛出更多有用的错误消息?也许您可以根据类型检查/值抛出警告?

在我看来,这与其说是语言问题,不如说是列表理解的限制,因为列表理解牺牲了通用性来换取简洁性;因此,不能在这样的表达式中间捕获异常。更详细的错误或警告消息可以通过简单的手动迭代轻松地再现,几乎没有性能或可读性损失:

vals = []
for k in bar.keys():
    # This uses the EAFP paradigm. An alternative is to check for
    # dictionary membership first
    try:
        vals.append(foo[k])
    except KeyError:
        raise SuperUsefulException(str(k))

由于编程语言明确支持这一点,因此这取决于模块作者。

老实说,正确的做法取决于模块的契约。在这种情况下,它应该抛出错误吗?它应该默默地忽略这种情况吗?

不幸的是,契约行为经常没有指定。在这种情况下,中间层调用者应该做出一个决定re:错误处理,以便返回一个有用的错误消息,因为顶层调用者对for和bar一无所知。

在这个答案中没有鸭子受到伤害。事实上,根本没有人参与。

最新更新