我不明白为什么作为第二个参数的instance函数需要一个元组而不是一些可迭代的?
isinstance(some_object, (some_class1, some_class2))
工作正常,但是
isinstance(some_object, [some_class1, some_class2])
引发TypeError
答案 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_object
是f
,o
,b
,a
还是r
的实例。
这显然不起作用,因此isinstance
将需要检查第二个参数是否不是字符串。由于isinstance
需要进行类型检查,因此最好确保第二个参数始终是元组。
答案 3 :(得分:0)
因为这是语言的设计方式...
编写代码可以接受多种类型的代码时,拥有可以直接测试的固定类型比使用duck typing容易。例如,由于字符串是可迭代的,因此当您要接受一个字符串序列中的一个字符串时,必须首先测试该字符串类型。
在这里,我可以想象出没有强烈的理由限制元组类型,但是也没有充分的理由将其扩展为任何序列。您可以尝试在python-ideas列表中提出建议。
答案 4 :(得分:-1)
从更高层次上来说,需要一个容器类型来进行实例检查,因此您具有内置容器的元组,列表,集合和字典。他们极有可能决定使用集合中的元组,因为isinstance的预期用例是少数类型,并且与集合相比,元组检查包含性的速度更快。
可变性确实不是一个考虑因素。如果他们确实需要不变性,则可以在处理之前将可迭代对象重新包装为元组。