【发布时间】:2021-07-06 18:20:33
【问题描述】:
Python 3.9 引入了Annotated 类,它允许将任意元数据添加到类型提示中,例如,
class A:
x: Annotated[int, "this is x"]
可以通过设置get_type_hints的新include_extras参数来获得带注释的类型提示:
>>> get_type_hints(A, include_extras=True)
{'x': typing.Annotated[int, 'this is x']}
并且元数据本身可以通过类型提示的__metadata__属性访问。
>>> h = get_type_hints(A, include_extras=True)
>>> h["x"].__metadata__
('this is x',)
但是,我的问题是,测试类型提示是否 是 Annotated 的正确方法是什么?也就是说,类似于:
if IS_ANNOTATED(h["x"]):
# do something with the metadata
据我所知,没有记录在案的方法可以做到这一点,并且有几种可能的方法,但似乎都不理想。
比较 type 和 Annotated 不起作用,因为类型提示不是 Annotated 的实例:
>>> type(h["x"])
typing._AnnotatedAlias
所以我们必须这样做:
if type(h["x"]) is _AnnotatedAlias:
...
但是,鉴于 _AnnotatedAlias 中的前导下划线,这可能需要使用实现细节。
另一种选择是直接检查__metadata__属性:
if hasattr(h["x"], "__metadata__"):
...
但这假设__metadata__ 属性是Annotated 独有的,在处理用户定义的类型提示时也不一定能假设。
那么,有没有更好的方法来做这个测试?
【问题讨论】:
-
我目前正在努力解决与此类似的问题 - 我无法为您提供答案,因为我无法提出比您的建议更好的建议。我相信目前没有官方方法来执行这种测试的原因是打字模块仍然是新的并且在每个python版本中都在迅速变化,所以不能保证API从版本到版本都保持不变版本。
-
通常你会为此使用鸭子打字。因此,您只需使用 try/except 块,而不是显式检查。
标签: python type-hinting python-typing