【发布时间】:2016-12-29 13:10:23
【问题描述】:
如何检查嵌套抽象类的完整类型签名?在这个例子中
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']
因此,获得嵌套类型似乎并不容易。我在文档中找不到相关信息。
附: 我需要这个来实现多分派。
更新
感谢 Alexander Huszagh 和 Blender 的反馈,我们现在知道 Python 3.5 中的抽象类(可能)有两个存储嵌套类型的属性:__parameters__ 和 __args__。前者在 Linux (Ubuntu) 和 Darwin (OS X) 下都存在,但在 Linux 的情况下它是空的。后者仅在 Linux 下可用,并存储像 __parameters__ 在 OS X 下所做的类型。这种实现细节增加了混乱。
【问题讨论】:
-
我希望接近投票者解释他的选择“有太多可能的答案,或者对于这种格式,好的答案太长了。请添加详细信息以缩小答案集或隔离一个可以在几段中回答的问题”。
-
isinstance(["hello"], int_seq)也是True。您确定在尝试使用打字而不是简单的类型检查时,您不会产生比解决更大的问题吗? -
@DmitryTorba 我正在尝试在 Python 中实现真正的多重分派,因此我需要分派器能够检查完整的类型签名。
-
@blender 帮我找到了找到序列类型的答案:
Sequence[int].__args__。Sequence[int].__parameters__似乎是特定于实现的。您可以将他现在删除的答案应用到相同的工作流程中。 -
你可能会发现这个模块很有用:github.com/fabiommendes/pygeneric
标签: python python-3.x oop python-3.5 type-hinting