是否可以在 Python 3.9 中嵌套 typing.Unions?

Is it possible to nest typing.Unions in Python 3.9?

是否可以在 Python 3.9.4 中嵌套 typing.Unions?

from typing import Union

TestValue = Union[int, str, float]

TestArray = Union[list, tuple]

TestListA = tuple[str, TestValue]

TestListB = TestArray[str, TestValue, TestValue]

在这段代码中,我在 TestListB:

行中得到一个异常
  File "C:\Python39\lib\typing.py", line 268, in inner
    return func(*args, **kwds)
  File "C:\Python39\lib\typing.py", line 751, in __getitem__
    _check_generic(self, params, len(self.__parameters__))
  File "C:\Python39\lib\typing.py", line 202, in _check_generic
    raise TypeError(f"{cls} is not a generic class")
TypeError: typing.Union[list, tuple] is not a generic class

我希望能够指定一个元组或列表,其中第一个条目是 str,而其他 2 个是 strintfloat.我的 linter 似乎流行起来,但 Python 本身却没有。

好吧,正如我从您的代码中了解到的,您想要 Union[list[str, TestValue, TestValue], tuple[str, TestValue, TestValue]] 这样的东西。但是您实际上正在做 Union[list, tuple][str, TestValue, TestValue] 这样的事情,这是不正确的。 也许ListContent = Union[str, TestValue, TestValue]; TestArray = Union[list[ListContent], tuple[ListContent]]是一个解决方案

不幸的是,您尝试做的是无效的 - 您不能像您所说的那样“嵌套”联合。那只是无效的键入语法。

此外,List类型将只接受一个参数——列表中所有项的类型(Sequence类型也是如此):

# This is valid
MyList = List[int]

# This will throw an exception:
MyList = List[int, str, str]

这与 Tuple 非常不同,在后者中您可以在固定大小的元组中定义每个项目的类型。因此,从 Python 的角度来看,将两者互换或拥有某种“超类型”并没有多大意义。

我不确定类型检查器是否知道如何检查列表是否恰好有 n 个项目。

如果可以的话,我会切换到始终对此类代码使用元组(甚至命名元组?) - 具有固定数量的项目和每个项目的特定类型的列表的整个想法有点反-直观。

否则,TBH 我不确定打字是否适合您 - 我能想到的最接近的类型是:

ItemType = Union[str, int, float]
SequenceType = Union[List[ItemType], Tuple[str, ItemType, ItemType]]

当然,这将允许用户传入任意长度的列表,其中包含 strintfloat 的任意组合的项目 - 但尽我所能知道你不能更严格地输入列表(你不应该)。