Python如何检查变量是否为列表中的任何一种类型?

171

如何简洁地执行以下操作:

var = 7.0
var_is_good = (
    isinstance(var, classinfo1) or
    isinstance(var, classinfo2) or
    isinstance(var, classinfo3)
)
5个回答

365

isinstance()函数的第二个参数是一个类元组。如果第一个参数是该序列中任何一种类型的实例,函数将返回True。

isinstance(var, (classinfo1, classinfo2, classinfo3))

换句话说,isinstance() 已经自带了这个功能。

来自 isinstance() 文档

如果 classinfo 不是类对象或类型对象,则 它可以是类或类型对象的元组,或递归地包含其他此类元组(不接受其他序列类型)。

注意其中的强调部分;这意味着 (classinfo1, (classinfo2, classinfo3)) 也是一个有效的选项。


34

18

你的问题标题已经很接近答案了。你可以使用 any 函数与列表:

var = 7.0
var_is_good = any([isinstance(var, classinfo1),
                   isinstance(var, classinfo2),
                   isinstance(var, classinfo3), ...
                   isinstance(var, classinfoN)])

但是查看isinstance文档后发现:

如果对象参数是类信息参数的实例,或者是其(直接、间接或虚拟)子类的实例,则返回true。如果对象不是给定类型的对象,则该函数始终返回false。如果classinfo不是一个类(type object),它可能是一组类型对象的元组,或者可以递归地包含其他这样的元组(不接受其他序列类型)。如果 classinfo 不是类型或类型的元组和这样的元组,则会引发 TypeError 异常。

这意味着更好的做法是

var = 7.0
var_is_good = isinstance(var, (classinfo1,
                               classinfo2,
                               classinfo3,
                               ...,
                               classinfoN))

3
在我的看法中,重复使用isinstance但只更改classinfo似乎不是很Pythonic。 - Makoto
1
尝试使用 var.__class__。这是你想要的吗?@Makoto:我同意。一点也不符合Python风格! - flamenco
@Makoto 是的。但是D Adams很可能可以通过在文档中搜索“any”来轻松找到这个问题的答案。我已经扩展了我的答案,以得到更好的版本...但是显然Martijn Pieters更快...再次证明了他的实力。 - Martin Thoma
4
如果你必须使用 any(),那么在列表中使用它是毫无意义的。如果你使用生成器表达式,至少可以获得提前退出的好处。 - Martijn Pieters
1
我认为使用元组的isinstance是正确的方法。我只是想提一下使用any的解决方案,因为它似乎是他在标题中所要求的。 - Martin Thoma

8
这将解决您的问题:
valid_instance_types = <tuple of types you want to allow>
var_is_good = isinstance(var, valid_instance_types)

根据文档,您可以使用许多方法将类型值传递给isinstance。如果您正在尝试进行更复杂的验证,那么您可能还需要查看(不幸命名的)voluptuous,其中包含本部分的一些内容。请注意保留HTML标记。

0

通常情况下,您不应该使用isinstance,但您想要做的可以通过any()内置函数来实现。

var_is_good = any(isinstance(var, t) for t in [type1, type2, type3])

13
"这太过了;isinstance()已经提供了功能,不需要使用any()。" - Martijn Pieters
@MartijnPieters 我之前不知道isinstance可以判断多个类型,但我认为这个答案仍然是一个好答案,因为这个问题可以被更广泛地解释为“如何检查特定函数的多个参数的返回值是否为true”。 - Chad S.
你是否应该使用isinstance()是无关紧要的。 - RFV
@ChadS。我想问你为什么认为他不应该使用isinstance()?谢谢。 - idature
因为Python避免类型检查。这会增加很多额外的代码(和CPU周期),但好处却很少。鸭子类型是首选。 - Chad S.
我知道这是一个旧的线程,但我必须介入。在Python3中,每个类都是一种类型,isinstance()提供了很多功能。如果没有isinstance,如果您尝试解析接受列表或字典的参数,则除了检查属性或捕获异常之外,isinstance似乎是最快的获取答案的方法。 - smcjones

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接