我使用赋值表达式(又名海象运算符,在PEP 572中定义)来定义类型T
。这似乎是一个优雅的解决方案,但显然我不同意。
对于以下代码:
# Python 3.10.4
from collections.abc import Sequence
from typing import TypeVar
def foo(seq: Sequence[T := TypeVar('T')]) -> T:
return seq[0]
mypy报告:
error: Invalid type comment or annotation
error: Name "T" is not defined
海象是否被禁止使用TypeVar
?
这是真的坏主意。
假设你将来导入了注释-那么这只是一个长字符串,没有赋值发生。假设你想在函数体中加入cast(T, something)
。如果mypy
接受这个,它会错过运行时错误:
NameError: name "T"未定义
所以在这种情况下,PEP563改变了代码的行为。
from __future__ import annotations
from collections.abc import Sequence
from typing import TypeVar
def foo(seq: Sequence[T := TypeVar('T')]) -> T:
return cast(T, seq[0])
您可以代替cast('T', ...)
,但这不是真正的注释情况。
从python 3.12开始(假设接受PEP695),将有可能使用更优雅和更强大的语法,用方括号替换TypeVar
:
from typing import Callable
def func[**P, R](cb: Callable[P, R], *args: P.args, **kwargs: P.kwargs) -> R:
...