[英]Python: recursive isinstance checking
How can one check a complete type signature of a nested abstract class? 如何检查嵌套抽象类的完整类型签名? In this example
在这个例子中
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
I want the last isinstance
call to actually return False
, while it only checks that the argument is a Sequence
. 我希望最后一个
isinstance
调用实际返回False
,而它只检查参数是否为Sequence
。 I thought about recursively checking the types, but IntSeq
has no public attributes that store the nested type(s): 我想过以递归方式检查类型,但
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']
So it doesn't seem to be straightforward to get nested types. 因此,获取嵌套类型似乎并不简单。 I can't find relevant information in the docs.
我在文档中找不到相关信息。
PS I need this for a multiple dispatch implementation. PS我需要这个用于多个调度实现。
Update 更新
Thanks to the feedback from Alexander Huszagh and Blender we now know that abstract classes in Python 3.5 (might) have two attributes that store the nested types: __parameters__
and __args__
. 感谢Alexander Huszagh和Blender的反馈,我们现在知道Python 3.5中的抽象类(可能)有两个存储嵌套类型的属性:
__parameters__
和__args__
。 The former is there under both Linux (Ubuntu) and Darwin (OS X), though it is empty in case of Linux. 前者存在于Linux(Ubuntu)和Darwin(OS X)之下,但在Linux的情况下它是空的。 The later is only available under Linux and stores the types like
__parameters__
does under OS X. This implementation details add up to the confusion. 后者仅在Linux下可用,并且在OS X下存储像
__parameters__
这样的类型。这种实现细节加起来很混乱。
I see you're trying to implement something using a module that is still provisional; 我看到你正在尝试使用仍然是临时的模块来实现某些功能; you're bound to encounter a changing interface if you do this.
如果你这样做,你将遇到一个不断变化的界面。
Blender noticed that the __parameters__
argument holds the parameters to the type; Blender注意到
__parameters__
参数保存了类型的参数; this was true until, I believe 3.5.1
. 这是真的,直到,我相信
3.5.1
。 In my git clone of the most recent version of Python ( 3.6.0a4+
) __parameters__
again holds an empty tuple, __args__
holds the argument and __origin__
is the first entry in its __bases__
attribute: 在我最新版本的Python(
3.6.0a4+
)的git克隆中, 3.6.0a4+
__parameters__
再次保存一个空元组, __args__
保存参数, __origin__
是其__bases__
属性中的第一个条目:
>>> intSeq = typing.Sequence[int]
>>> intSeq.__args__
(<class 'int'>,)
>>> intSeq.__parameters__
()
>>> intSeq.__origin__
typing.Sequence<+T_co>
Since 3.6
is when typing will, from what I understand from PEP 411
, leave provisional and enter a stable state, this is the version you should be working with to implement your functionality. 因为
3.6
是打字的时候,根据我从PEP 411
理解,保留临时状态并进入稳定状态,这是你应该用来实现你的功能的版本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.