如何为赋值注解的类型别名绑定mypy类型变量及差异原因?
问题描述
先看这段Python代码:
from typing import Callable, TypeVar T = TypeVar('T') IndicatorFunction = Callable[[T], bool] # mypy 接受这个注解 s1: Callable[[T], bool] = lambda x: False # mypy 拒绝这个注解,但它本质是第一个类型的别名 s2: IndicatorFunction[T] = lambda x: False
运行mypy后收到错误:
main.py:9: error: Type variable "__main__.T" is unbound main.py:9: note: (Hint: Use "Generic[T]" or "Protocol[T]" base class to bind "T" inside a class) main.py:9: note: (Hint: Use "T" in function signature to bind "T" inside a function) Found 1 error in 1 file (checked 1 source file)
有两个疑问:
- 如何让s2的类型注解中T被mypy认可已绑定?
- 为什么s1的注解没报错?IndicatorFunction是s1类型的别名,本该两者都被接受才对。
解答
1. 让s2的T被绑定的方法
顶层作用域里不能直接使用未绑定的泛型类型别名,有两种常见解决方式:
方式一:指定具体类型
如果已经确定IndicatorFunction的参数类型,直接把T替换成具体类型即可:
s2: IndicatorFunction[int] = lambda x: False
方式二:放在泛型函数/类中绑定T
如果需要保留泛型特性,把赋值逻辑放到泛型函数里,让函数签名来绑定TypeVar:
from typing import Callable, TypeVar T = TypeVar('T') IndicatorFunction = Callable[[T], bool] def create_indicator() -> IndicatorFunction[T]: return lambda x: False # 使用时会根据上下文自动推断T的具体类型 s2 = create_indicator()
2. 为什么s1没问题而s2报错?
这是mypy对两种写法的处理逻辑差异:
- 对于
Callable[[T], bool]这种直接书写的泛型Callable类型,mypy会将未绑定的T视为存在量化类型——简单说就是“这个函数可以接受任意类型的参数并返回bool”,相当于隐式允许了未绑定的TypeVar,所以不会报错。 - 而
IndicatorFunction[T]是你定义的显式泛型类型别名,mypy对泛型别名的使用有严格要求:TypeVar必须被显式绑定(要么指定具体类型,要么通过函数/类的泛型签名绑定)。因为类型别名是显式的泛型包装,mypy会强制检查它的泛型参数是否合法绑定,所以抛出了错误。
内容的提问来源于stack exchange,提问作者Connor Clark
相关产品推荐
相关产品推荐

