解包 Python 3.5.2 中的可选类型注释

Unpack Optional type annotation in Python 3.5.2

提问人:deceze 提问时间:9/13/2017 最后编辑:Martijn Pietersdeceze 更新时间:8/7/2021 访问量:4404

问:

在此示例中:

import typing

def foo(bar: int = None):
    pass

typing.get_type_hints(foo)

的类型提示是 。我该如何从中得到?在 Python 3.5.2 中,nor 属性似乎都不起作用。bartyping.Union[int, None]int__args____parameters__


更具体地说,我正在尝试编写一个通用装饰器,用于检查函数的签名并对参数执行特定操作。为此,它需要从注解中获取类,例如,然后使用:Optional[T]T

annot = typing.Optional[T]
cls = # MAGIC?!
assert cls is T
python-3.x 注解 类型提示

评论

1赞 Dimitris Fasarakis Hilliard 9/13/2017
似乎您正在寻找(至少在)。您使用的是哪个 Python 版本? 仍然是临时的,因此仍可能进行更改。annot.__args__[0]3.6.1typing
0赞 deceze 9/13/2017
现在需要在 3.5 上工作。
0赞 Dimitris Fasarakis Hilliard 9/13/2017
你在用我猜?在我认为是命名的,所以请注意这一点(模块的内部 API 非常不稳定。3.5.23.5.1__args____parameters__typing
0赞 Dimitris Fasarakis Hilliard 9/13/2017
啊,对了,我回答了类似的问题:stackoverflow.com/questions/38703556/......
0赞 deceze 9/13/2017
是的,我只是用不同的版本来玩它,确实存在一些差异......

答:

3赞 MSeifert 9/13/2017 #1

在这些情况下,我更愿意简单地咨询实现。在 3.5.2 中,这是 Union 的__repr__

def __repr__(self):
    r = super().__repr__()
    if self.__union_params__:
        r += '[%s]' % (', '.join(_type_repr(t)
                                 for t in self.__union_params__))
    return r

这表明该类存储在以下属性中:__union_params__

typing.get_type_hints(foo)['bar'].__union_params__[0] is T

但是,在 3.5.3 的提交 5fc25a873cfdec27e46f71e62c9b65df5667c1b4 中,这已更改为。__args__

8赞 Dimitris Fasarakis Hilliard 9/13/2017 #2

在 中,要获取 的参数,您必须使用 。3.5.2Union__union_params__

>>> from typing import Union
>>> d = Union[int, str]
>>> print(*d.__union_params__)
<class 'int'> <class 'str'>

不幸的是,这似乎适用于,直到它被更改为使用:3.5.23.5.3__args__

>>> from typing import Union
>>> t = Union[int, str]
>>> t.__union_params__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: '_Union' object has no attribute '__union_params__'
>>> print(*t.__args__)
<class 'int'> <class 'str'>

并保留在更高版本( 和 )。__args__3.63.7

这是由于类型化模块的临时状态所致。内部 API 的许多方面在微版本之间都在变化,因此您可能需要处理许多晦涩难懂的更改。