Python:鸭子类型与异常处理

cha*_*ker 5 python types duck-typing exception

关于 idomatic Python 的问题。假设我有一个函数:

def a_function(list_of_things):
    for item in list_of_things:
        process_item(item)
Run Code Online (Sandbox Code Playgroud)

现在假设我很难确定输入参数是一个列表。即使是现在,我仍然可以听到甜美的 Pythonista 合唱团恳求我:“使用鸭子类型和例外!”

def a_function(list_of_things):
    try:
        for item in list_of_things:
            process_item(item)
    except:
        pass # . . . or something
Run Code Online (Sandbox Code Playgroud)

这很棒,除非我传入一个映射、一个字符串或任何其他可迭代的东西,而我发现对于这个特定的应用程序来说这是“错误的”。

我并没有编写大量的Python,但我经常遇到这种情况和相关的情况,这足以让我经常烦恼。更一般地说,我想使用鸭子类型和异常,这似乎是 Python 中的约定,但在很多情况下可能会得到传递异常的错误输入类型;如此多的例外情况似乎常常是错误的答案(或者至少经常如此)。

即使异常看起来确实正确的答案,当我使用它们时我仍然感到害怕,因为如果我只是没有想到坏类型会通过的极端情况,留下我的代码,因为缺乏更好的术语怎么办,“躲开”。

所以我最终求助于诸如type和 之类的东西isinstance。根据我的阅读,显式类型检查在 Python 中似乎被认为是邪恶的,但是还能做什么呢?请注意,我几乎从未在 Python 中编写类层次结构,因此我在子类和类型检查方面没有问题,但其他人可能会。

我想到了四种可能的答案,所有这些对我来说似乎都同样可能:

  1. 您应该使用异常,但您做错了。像这样做 。。。
  2. 您应该使用异常。如果错误的类型通过了您的检查,则表明您的设计存在一些问题(什么问题?)
  3. 你正在做正确的事。在这些情况下,最好进行显式类型检查。
  4. 你不知道吗<python thing for this situation>?做一些研究!

是其中之一,还是其他?

注意-我在SO上发现了很多关于这个问题的回避问题,但我正在寻找人们来谈论这个特定的“类型”的问题,如果他们可以的话。

Dan*_*iel 3

最佳实践是与类型无关。-loopfor会引发任何不可迭代类型的异常。文档应清楚地说明需要可迭代类型。使用您的函数的函数应该进行单元或集成测试,以便发现意外的行为。