Python isinstance函数

时间:2019-05-06 08:21:29

标签: python

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

isinstance(some_object, (some_class1, some_class2))

工作正常,但是

isinstance(some_object, [some_class1, some_class2])

引发TypeError

5 个答案:

答案 0 :(得分:3)

原因似乎是“仅允许元组就足够了,它更简单,避免了某些极端情况的危险,并且对于BDFL似乎更整洁了”(即Guido)。 (对@Caleb表示感谢,以便在评论中发布关键链接。)

这里是this email conversation with Guido van Rossum的摘录,专门摘录了isinstance函数的其他可迭代项的情况。 (单击链接可进行完整的对话。)

  

James Powell在2014年1月2日星期四下午1:37写道:

     
    

这是由一个真实的例子驱动的,其中大量     存储在集合中的前缀,必须:

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

这些都不会让我感到震惊。另外,取决于是否设置   前缀本身会动态更改,因此最好取消   从startwith()调用中调用tuple()调用。

     

...

     
    

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

isinstance(x, {int, float})
  
     

但这具有动态生成的参数的可能性更低。

     

这里仍然可能存在另一种歧义:元类可以   可以想象它的实例(即类)是可迭代的。

答案 1 :(得分:1)

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

  

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

答案 2 :(得分:0)

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

isinstance(some_object, 'foobar')

,它将检查some_objectfoba还是r的实例。

这显然不起作用,因此isinstance将需要检查第二个参数是否不是字符串。由于isinstance需要进行类型检查,因此最好确保第二个参数始终是元组。

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:-1)

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

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