如何使用类型注释在 Python 中注释可变参数?
Posted
技术标签:
【中文标题】如何使用类型注释在 Python 中注释可变参数?【英文标题】:How to annotate variadic parameters in Python using typing annotations? 【发布时间】:2018-08-01 06:09:00 【问题描述】:如何标注变参函数的参数?
例子:
def foo(*args): # Each arg expected to be of type T
...
是否有任何打字注释?
【问题讨论】:
【参考方案1】:如果每个参数都有一个TheType
类型 - 按照PEP-484 中的说明对其进行注释:
def foo(*args: TheType):
...
不要使用:,因为指定 def foo(*args: Tuple[TheType]):
Tuple[TheType]
意味着它是一个单元素元组 - 带有一个 TheType
元素,这不是可变参数 args 的用途。
【讨论】:
好吧,指定Tuple[TheType]
实际上意味着您期望TheType
类型的元组作为变量参数。 本身 args
已经是一个同构元组,星号只是扩展它。这就是为什么您只留下注释类型。【参考方案2】:
tl;博士
基本上args
被视为同质元组,kwds
被视为字典。
您只需为每个元素值注释一个类型即可。
说明
解释来自 PEP-484 的quote:
在函数foo的主体中,推导出变量args的类型为
Tuple[str, ...]
,变量kwds的类型为Dict[str, int]
。
因此,无需将 args 注释为整个同质类型元组,但可以将 Tuple[T, ...]
简化为仅键入 T
。
关键字参数与推断为 Dict[str, T]
相同
关于元组注释中的省略号
在 python 文档中没有太多关于...
aka Ellipsis
使用的信息,但是 PEP-484 确实提到了省略号在键入注释时的各种用法,例如省略某些类型注释或默认值,但最有趣的是那里是qoute 说:
元组,用于列出元素类型,例如
Tuple[int, int, str]
。空元组可以输入为Tuple[()]
。任意长度 同质元组可以使用一种类型和省略号来表示,对于 例如Tuple[int, ...]
。 (这里的...
是语法的一部分,a 字面省略号。)
因此,如果您省略星号以强制将参数作为单个元组传递,则需要保留完整的注释:
def foo(args: Tuple[T, ...]):
...
关于同质元组中的各种类型
由于同构元组意味着它的所有元素必须是相同的类型,那么如果您希望允许多个类型,只需使用 Union
或者甚至使用类型别名以获得更好的可读性:
MyArg = Union[int, str, bool]
def foo(*args: MyArg):
...
【讨论】:
你确定这是正确的方法吗?根据the pep,可变参数没有被注释为Tuple
,而是像def foo(*args: str):
(而不是Tuple[str]
)。那么,您的注释不是意味着您的函数接受可变数量的同质元组吗?
嗯……我可能错过了,因为我在寻找省略号,因为我记得有一种涉及它的方法。此外,我发现将其注释为Tuple
没有问题,并且在函数内,它确实通过了测试isinstance(args, tuple)
。请注意没有*
星号。我相信*args: T
是*args: Tuple[T, ...]
的简写,所以我没有发现任何问题。
嗯,@Aran-Fey PyCharm 和今天的 IDEA 不能正确理解完整的语法,也不能正确识别你提到的较短版本。
@kuza 您接受了您对自己问题的回答,但问题是它不正确。
好吧,我在更新后确实纠正了自己,引用了 PEP 484。也许是 tl;dr 适合你?我会尽量缩小我的答案。以上是关于如何使用类型注释在 Python 中注释可变参数?的主要内容,如果未能解决你的问题,请参考以下文章