Python:递归isinstance检查

时间:2016-08-22 21:06:05

标签: python python-3.x oop python-3.5 type-hinting

如何检查嵌套抽象类的完整类型签名?在这个例子中

In [4]: from typing import Sequence

In [5]: IntSeq = Sequence[int]

In [6]: isinstance([1], IntSeq)
Out[6]: True

In [7]: isinstance([1.0], IntSeq)
Out[7]: True

我希望最后一次isinstance调用实际返回False,而它只检查参数是否为Sequence。我想过以递归方式检查类型,但是IntSeq没有存储嵌套类型的公共属性:

In [8]: dir(IntSeq)
Out[8]: 
['__abstractmethods__',
 '__class__',
 '__delattr__',
 '__dict__',
 '__dir__',
 '__doc__',
 '__eq__',
 '__extra__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__gt__',
 '__hash__',
 '__init__',
 '__le__',
 '__len__',
 '__lt__',
 '__module__',
 '__ne__',
 '__new__',
 '__origin__',
 '__parameters__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__setattr__',
 '__sizeof__',
 '__slots__',
 '__str__',
 '__subclasshook__',
 '__weakref__',
 '_abc_cache',
 '_abc_negative_cache',
 '_abc_negative_cache_version',
 '_abc_registry']

因此,获取嵌套类型似乎并不简单。我在文档中找不到相关信息。

P.S。 我需要这个用于多个调度实现。

更新

感谢Alexander Huszagh和Blender的反馈,我们现在知道Python 3.5中的抽象类(可能)有两个存储嵌套类型的属性:__parameters____args__。前者存在于Linux(Ubuntu)和Darwin(OS X)之下,但在Linux的情况下它是空的。后者仅在Linux下可用,并且在OS X下存储像__parameters__这样的类型。这种实现细节加起来很混乱。

1 个答案:

答案 0 :(得分:2)

我看到你正在尝试使用仍然是临时的模块来实现某些功能;如果你这样做,你将会遇到一个不断变化的界面。

Blender注意到__parameters__参数保存了该类型的参数;这是真的,直到,我相信3.5.1。在我最新版本的Python(3.6.0a4+__parameters__的git克隆中再次保存一个空元组,__args__保存参数,__origin__是其{的第一个条目{1}}属性:

__bases__

由于>>> intSeq = typing.Sequence[int] >>> intSeq.__args__ (<class 'int'>,) >>> intSeq.__parameters__ () >>> intSeq.__origin__ typing.Sequence<+T_co> 是在输入时,根据我从PEP 411的理解,保留临时状态并进入稳定状态,这是您应该使用的版本来实现您的功能。