typing: TypeVar vs. Union, mypy error: Missing type parameters for generic type

typing: TypeVar vs. Union, mypy error: Missing type parameters for generic type

尽管在 typing documentation, the mypy documentation, and PEP 483.

中花费了大量时间,但我仍在努力理解何时使用 TypeVar 以及何时使用 Union

问题的简单版本:Numeric = TypeVar('Numeric', int, float)Numeric = Union[int, float] 之间有什么区别?

这是我 运行 的更详细示例:

"""example1.py
Use of Union to define "Numeric" type.
"""

from typing import Union, Sequence

Numeric = Union[int, float]

Vector = Sequence[Numeric]

Matrix = Sequence[Vector]

用mypy检查:

$ mypy --strict example1.py
Success: no issues found in 1 source file 

改用TypeVar

"""example2.py
Use of TypeVar to define "Numeric" type.
"""

from typing import TypeVar, Sequence

Numeric = TypeVar('Numeric', int, float)

Vector = Sequence[Numeric]

Matrix = Sequence[Vector]

用mypy检查:

$ mypy --strict example2.py
example2.py:11: error: Missing type parameters for generic type "Vector"
Found 1 error in 1 file (checked 1 source file)

上面的mypy错误是指Matrix的定义。为什么 mypyexample1.py 满意,但对 example2.py 不满意?

我可以通过将最后一行更改为 Matrix = Sequence[Vector[Numeric]].

来消除 example2.py 中的错误

版本信息:

$ python --version
Python 3.8.4
$ mypy --version
mypy 0.782

TypeVar 用于创建通用类型。

Numeric = TypeVar('Numeric', int, float)

Vector = Sequence[Numeric]

... 表示 Vector[T]Sequence[T] 的别名,但具有 issubclass(T, (int, float)) 的约束。这意味着 mypy 认为 Vector 是一个不完整的类型,它会问:“什么的向量?”,你可以写 Vector[Numeric] 来表示:“任何数字的向量”。

常用于函数或类,像这样:

T = TypeVar('T')
V = TypeVar('V')
def map(f: Callable[[T], V], it: Iterable[T]) -> Iterator[V]:
    for x in it:
        yield f(x)

这意味着您可以制作东西type-safe,即使您不确切知道您将得到什么类型。