如何使用类型注释在 Python 中注释可变参数?

mis*_*ope 8 python typing pep

如何注释可变参数函数的参数?

例子:

def foo(*args):  # Each arg expected to be of type T
    ...
Run Code Online (Sandbox Code Playgroud)

是否有任何打字注释?

Mik*_*son 6

如果每个参数都有一个TheType类型 - 按照PEP-484中的指定对其进行注释:

def foo(*args: TheType):
    ...
Run Code Online (Sandbox Code Playgroud)

不要使用: def foo(*args: Tuple[TheType]):,因为指定Tuple[TheType]意味着它是一个单元素元组 - 只有一个TheType元素,这不是可变参数的目的。


mis*_*ope 5

太长了;博士

基本上args被视为同质元组和kwds字典。您只需注释每个元素值所需的类型即可。

解释

解释来自PEP-484 的引用:

在函数 foo 的主体中,变量 args 的类型推导为Tuple[str, ...],变量 kwds 的类型为Dict[str, int]

因此,无需将 args 注释为整个同构类型元组,但可以简化Tuple[T, ...]为仅 type T

对于关键字参数来说也是如此,因为他们推断为Dict[str, T]

关于元组注释中的省略号

在 python 文档中,没有太多关于 aka 用法的信息...Ellipsis但 PEP-484 确实提到了省略号在键入注释中的各种用法,例如省略某些类型注释或默认值,但最有趣的是有一句话

元组,通过列出元素类型来使用,例如Tuple[int, int, str]。空元组可以键入为Tuple[()]。例如,可以使用一种类型和省略号来表示任意长度的同质元组Tuple[int, ...]。(...这里是语法的一部分,字面省略号。)

因此,如果您省略星号以强制将参数作为单个元组传递,则需要保留完整注释:

def foo(args: Tuple[T, ...]):
    ...
Run Code Online (Sandbox Code Playgroud)

关于同构元组中的各种类型

由于同构元组意味着它的所有元素必须属于同一类型,因此如果您希望允许多种类型,只需使用Union甚至使用类型别名以获得更好的可读性:

MyArg = Union[int, str, bool]

def foo(*args: MyArg):
    ...
Run Code Online (Sandbox Code Playgroud)

  • 你确定这是正确的方法吗?根据 [the pep](https://www.python.org/dev/peps/pep-0484/#centric-argument-lists-and-default-argument-values) varargs 没有注释为“Tuple”,而是像 `def foo(*args: str):` (而不是 `Tuple[str]`)。那么,您的注释是否意味着您的函数接受可变数量的同质元组? (2认同)