Python检查isinstance列表中的任何类型?

时间:2015-10-23 20:57:00

标签: python types isinstance

我如何做pythonicly:

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

看起来很傻我不能只传入classinfo的列表:

var_is_good = isinstanceofany( var, [classinfo1, classinfo2, ... , classinfoN] )

那么isinstanceofany函数是什么?

5 个答案:

答案 0 :(得分:84)

isinstance()为第二个参数提供类的元组。如果第一个参数是该序列中任何类型的实例,它将返回true:

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

换句话说,isinstance() 已经提供开箱即用的此功能。

来自isinstance() documentation

  

如果 classinfo 既不是类对象也不是类型对象,它可能是类或类型对象的元组,或者可能递归地包含其他这样的元组(不接受其他序列类型) )。

强调我的;注意递归性质; (classinfo1, (classinfo2, classinfo3))也是一个有效选项。

答案 1 :(得分:5)

你已经非常接近问题的标题了。您可以使用any和列表:

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

但是查看isinstance的文档会发现:

  

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

这意味着更好的方法是

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

答案 2 :(得分:4)

这将解决您的问题:

valid_instance_types = <tuple of types you want to allow>
var_is_good = isinstance(var, valid_instance_types)

根据documentation,您可以通过多种方式将类型值传递到isinstance

如果您正在尝试进行更复杂的验证,您可能会调查voluptuous,而这只是其中的一部分。

答案 3 :(得分:4)

从 Python 3.10 开始,您可以使用新的 New Type Union Operator,例如:

isinstance(var, classinfo1 | classinfo2)

有关详细信息,请参阅 PEP 604

答案 4 :(得分:3)

您通常不应该使用isinstance,但您可以使用any()内置函数完成您想要做的事情。

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