【问题标题】:Python isinstance functionPython isinstance 函数
【发布时间】:2019-05-06 08:21:28
【问题描述】:

我不明白为什么 isinstance 函数作为第二个参数需要一个元组而不是一些可迭代的?

isinstance(some_object, (some_class1, some_class2))

工作正常,但是

isinstance(some_object, [some_class1, some_class2])

引发类型错误

【问题讨论】:

  • this 问题可能会有所帮助。
  • 链接问题的答案为为什么提供了一个良好的开端。每个人都应该在此处发布答案之前阅读它。
  • 比你凯莱布!这有助于我理解原因。

标签: python


【解决方案1】:

原因似乎是“只允许元组就足够了,它更简单,它避免了一些极端情况的危险,而且对 BDFL 来说似乎更整洁”(即 Guido)。 (感谢 @Caleb 在 cmets 中发布关键链接。)

这是this email conversation with Guido van Rossum 的摘录,专门针对isinstance 函数的其他可迭代对象的情况。 (点击链接查看完整对话。)

2014 年 1 月 2 日星期四下午 1:37,詹姆斯鲍威尔写道:

这是由一个真实世界的示例驱动的,其中大量 存储在集合中的前缀,需要:

any('spam'.startswith(c) for c in prefixes)
# or
'spam'.startswith(tuple(prefixes))

这些都没有让我觉得很糟糕。另外,取决于是否设置 前缀本身是动态变化的,最好解除 tuple() 从startswith() 调用中调用。

...

但是,.startswith 似乎并不是唯一的例子,而且 其他示例没有字符串/可迭代歧义:

isinstance(x, {int, float})

但这更不可能有动态生成的参数。

这里可能还有另一个歧义:元类可以 可以想象使其实例(即类)可迭代。

【讨论】:

  • @Fanto 如果答案有帮助,请点击投票按钮下方的复选标记接受。
  • 顺便说一句,感谢这个问题,我了解到str.startswith() 可以将元组作为参数! :-) 我从没想过要检查。
【解决方案2】:

根据文档:https://docs.python.org/3/library/functions.html#isinstance

如果 classinfo 是类型对象的元组(或递归地,其他此类元组),如果 object 是任何类型的实例,则返回 true。如果 classinfo 不是类型或类型的元组和此类元组,则会引发 TypeError 异常。

【讨论】:

  • 这并不能真正回答为什么会出现这种情况。
  • 查看@Caleb 发布的链接:这是一个不相关的问题,但它解释了某些函数只接受元组的原因。
【解决方案3】:

因为字符串也是“一些可迭代的”。所以你可以写:

isinstance(some_object, 'foobar')

它会检查some_object 是否是fobar 的实例。

这显然行不通,所以isinstance 需要检查第二个参数是否不是字符串。由于isinstance 需要做类型检查,所以最好确保第二个参数始终是一个元组。

【讨论】:

    【解决方案4】:

    因为这是语言的设计方式...

    当您编写代码可以接受多于一种类型时,使用可以直接测试的固定类型比使用duck typing 更容易。例如,由于字符串是可迭代的,所以当您想要接受字符串序列中的一个字符串时,您必须首先测试字符串类型。

    在这里,我可以想象没有充分的理由限制元组类型,但也没有充分的理由将其扩展到任何序列。您可以尝试在python-ideas 列表中提出它。

    【讨论】:

    • 请不要尝试在 python-ideas 上提出它!他们已经超越了那个领域,并决定反对它。
    【解决方案5】:

    在高层次上需要一个容器类型来进行 isinstance 检查,因此您有用于内置容器的元组、列表、集合和字典。最有可能的是,他们决定使用元组而不是集合,因为 isinstance 的预期用例是少数类型,并且与集合相比,元组检查包含的速度更快。

    可变性确实不是一个考虑因素。如果他们真的需要不变性,他们可以在处理之前将可迭代对象重新包装成一个元组。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 2016-12-29
      • 2018-11-28
      • 1970-01-01
      • 2021-07-25
      相关资源
      最近更新 更多