尽管在typing documentation,mypy documentation和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
的定义。为什么mypy
对example1.py
满意但对example2.py
不满意?
通过将最后一行更改为example2.py
,我可以消除Matrix = Sequence[Vector[Numeric]]
中的错误。
版本信息:
$ python --version
Python 3.8.4
$ mypy --version
mypy 0.782
答案 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)
这意味着即使您不确切知道要获得哪种类型,也可以使类型安全。