如何为函数双参数加类型注解:约束同类型且排除numpy.ndarray
解决类型注解约束:确保相等比较返回bool且参数类型一致
核心思路
要实现你的需求,关键是通过Protocol定义严格的相等比较约束,结合泛型TypeVar强制参数类型一致,让Pyright识别并排除numpy.ndarray这类违反LSP的类型。
步骤1:定义严格相等比较的Protocol
显式声明一个协议,要求__eq__方法必须返回bool,过滤掉返回非布尔值的类型:
from typing import Protocol, TypeVar, Any class SupportsStrictEq(Protocol): def __eq__(self, other: Any) -> bool: ...
这个协议会自动排除numpy.ndarray——因为它的__eq__返回的是布尔数组而非单个bool。
步骤2:绑定协议的泛型TypeVar
创建绑定到上述协议的泛型变量,确保函数的两个参数类型完全相同:
T = TypeVar('T', bound=SupportsStrictEq)
步骤3:给函数添加类型注解
用泛型T标注参数,同时指定返回值类型:
def simple_compare(a: T, b: T) -> bool: return a == b
步骤4:开启Pyright严格模式
如果Pyright未检测到numpy.ndarray的错误,检查你的pyrightconfig.json是否开启严格模式,确保结构类型检查生效:
{ "strict": true }
验证效果
- 合法调用(Pyright无报错):
simple_compare(10, 20) # int类型,符合约束 simple_compare("hello", "world") # str类型,符合约束 - 非法调用(Pyright会触发错误):
import numpy as np arr_a = np.array([1, 2]) arr_b = np.array([3, 4]) simple_compare(arr_a, arr_b) # 错误:numpy.ndarray不满足SupportsStrictEq协议 simple_compare(10, "20") # 错误:两个参数类型不一致(int vs str)
特殊场景兜底
如果遇到第三方库类型定义不严谨的情况,可以结合TypeGuard做类型+运行时的双重约束:
import numpy as np from typing import TypeGuard def is_valid_eq_type(x: Any) -> TypeGuard[SupportsStrictEq]: return not isinstance(x, np.ndarray) def simple_compare(a: T, b: T) -> bool: assert is_valid_eq_type(a), "禁止传入numpy.ndarray类型" assert is_valid_eq_type(b), "禁止传入numpy.ndarray类型" return a == b
内容的提问来源于stack exchange,提问作者Vexx23
相关产品推荐
相关产品推荐

