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

D A*_*ams 56 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)
Run Code Online (Sandbox Code Playgroud)

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

var_is_good = isinstanceofany( var, [classinfo1, classinfo2, ... , classinfoN] )
Run Code Online (Sandbox Code Playgroud)

那么isinstanceofany功能是什么?

Mar*_*ers 122

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

isinstance(var, (classinfo1, classinfo2, classinfo3))
Run Code Online (Sandbox Code Playgroud)

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

isinstance()文档:

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

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


Chr*_*nds 36

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

isinstance(var, classinfo1 | classinfo2)
Run Code Online (Sandbox Code Playgroud)

详细信息请参阅PEP 604


Nat*_*ord 8

这将解决您的问题:

valid_instance_types = <tuple of types you want to allow>
var_is_good = isinstance(var, valid_instance_types)
Run Code Online (Sandbox Code Playgroud)

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

如果您尝试进行更复杂的验证(这只是其中的一部分),您也可能会考虑(不幸的是,它的名字)voluptous 。


Mar*_*oma 7

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

var = 7.0
var_is_good = any([isinstance(var, classinfo1),
                   isinstance(var, classinfo2),
                   isinstance(var, classinfo3), ...
                   isinstance(var, classinfoN)])
Run Code Online (Sandbox Code Playgroud)

但是看看文档isinstance揭示:

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

这意味着更好的方法是

var = 7.0
var_is_good = isinstance(var, (classinfo1,
                               classinfo2,
                               classinfo3,
                               ...,
                               classinfoN))
Run Code Online (Sandbox Code Playgroud)

  • 对我而言,仅更改classinfo重复执行isinstance似乎并不十分Python化。 (2认同)
  • 带列表的`any()`是没有意义的.如果必须使用`any()`,请使用生成器表达式,然后至少可以获得早期退出的好处. (2认同)