如何注释采用可变长度元组的函数? (可变元组类型注解)

How to annotate function that takes a tuple of variable length? (variadic tuple type annotation)

我有一个函数,它接受一个不同长度的元组作为参数:

from typing import Tuple


def process_tuple(t: Tuple[str]):
    # Do nasty tuple stuff

process_tuple(("a",))
process_tuple(("a", "b"))
process_tuple(("a", "b", "c"))

当我像上面提到的那样注释函数时,我收到这些错误消息

fool.py:9: error: Argument 1 to "process_tuple" has incompatible type "Tuple[str, str]"; expected "Tuple[str]"
fool.py:10: error: Argument 1 to "process_tuple" has incompatible type "Tuple[str, str, str]"; expected "Tuple[str]"

process_tuple 确实适用于元组,我将它们用作可变长度的不可变列表。我在互联网上没有找到关于这个主题的任何共识,所以我想知道我应该如何注释这种输入。

我们可以像这样使用 ... 文字(又名 Ellipsis)来注释可变长度的同构元组:

def process_tuple(t: Tuple[str, ...]):
    ...

或 Python3.9+

def process_tuple(t: tuple[str, ...]):
    ...

之后,错误应该会消失。

来自docs

To specify a variable-length tuple of homogeneous type, use literal ellipsis, e.g. Tuple[int, ...]. A plain Tuple is equivalent to Tuple[Any, ...], and in turn to tuple.

除了 Azat 发布的省略号答案之外,您还可以使用 @typing.overload or typing.Union

使其更加明确
from typing import Tuple


@overload
def process_tuple(t: Tuple[str]):
    # Do nasty tuple stuff

@overload
def process_tuple(t: Tuple[str, str]):
    ...

或加入联盟:

from typing import Tuple, Union


def process_tuple(t: Union[Tuple[str], Tuple[str, str], Tuple[str, str, str]]):
    # Do nasty tuple stuff

Python 3.9+

使用tuple:

def process_tuple(t: tuple[str, ...]):
    pass

自 Python 3.9 起,typing.Tuple 已贬值。 typing.Tupledocumentation 状态:

Deprecated since version 3.9: builtins.tuple now supports [].

Python 3.8 及更早版本

如果您使用的是 Python 3.8 或更早版本,您仍应使用 typing.Tuple:

from typing import Tuple

def process_tuple(t: Tuple[str, ...]):
    pass