如何为处理Any类型参数的函数正确编写重载类型注解?
如何编写适配Any类型特殊场景的重载类型注解?
我有一个返回类型对多参数敏感的函数:若传入的断言能提供足够强的类型约束,输入值也会被相应约束(如T | None -> T或T -> R where R <: T)。当所有类型明确时,类型注解的写法很直接:
from typing import Any, Callable, Iterable, Iterator, TypeGuard, TypeVar, overload T = TypeVar("T") R = TypeVar("R") @overload # 1 def select(pred: None, values: Iterable[T | None]) -> Iterator[T]: ... @overload # 2 def select(pred: Callable[[T], TypeGuard[R]], values: Iterable[T]) -> Iterator[R]: ... @overload # 3 def select(pred: Callable[[T], Any], values: Iterable[T]) -> Iterator[T]: ...
但当参数类型未知时会出现问题:若断言为Any类型,预期应施加最少类型约束,输出类型与输入值一致。然而现有类型检查器的表现不符合预期:MyPy会将类型完全泛化为Iterator[Any],PyRight则匹配None特殊场景,给出过度约束的Iterator[int]。
调整重载顺序无法解决问题:若按2-3-1排序,Any无法提供R类型,类型检查器无法回退到T;若按3-2-1排序,(T) -> Any会完全覆盖(T) -> TypeGuard[R]。
1 基于以下前置代码:
from typing import Any, reveal_type iitr: list[int | None] = [0, 1, 2, None, 3] any_pred: Any = lambda val: not val # 可为任意未知函数
使用未知断言时,测试的类型检查器均存在不同问题:
| 用例 | 预期结果 | MyPy | PyRight |
|---|---|---|---|
select(None, iitr) | Iterator[int] | Iterator[int] | Iterator[int] |
select(bool, iitr) | Iterator[int | None] | Iterator[int | None] | Iterator[int | None] |
select(any_pred, iitr) | Iterator[int | None] | Iterator[Any] | Iterator[int] |
内容的提问来源于stack exchange,提问作者MisterMiyagi
相关产品推荐
相关产品推荐

