键入:TypeVar与联合,mypy错误:通用类型缺少类型参数

时间:2020-09-16 17:26:07

标签: python python-3.x typing mypy python-typing

尽管在typing documentationmypy documentationPEP 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不满意?

通过将最后一行更改为example2.py,我可以消除Matrix = Sequence[Vector[Numeric]]中的错误。

版本信息:

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

1 个答案:

答案 0 :(得分:1)

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)

这意味着即使您不确切知道要获得哪种类型,也可以使类型安全。