正确运行的代码无法通过mypy类型检查,疑为泛型问题
自定义中缀运算符的类型安全实现(兼容mypy --strict)
你实现的中缀运算符语法逻辑可行,但因泛型类型注解不完整,导致mypy无法正确推断类型参数,从而触发检查错误。以下是修正后的实现,既能保持原有语法,又能通过mypy --strict的严格类型检查:
""" 类型安全的自定义中缀运算符实现 支持 leftArgument <<functionName>> rightArgument 语法 可通过 mypy --strict 检查 """ from typing import Callable, Generic, TypeVar # 定义泛型类型变量,对应函数的左参数、右参数、返回值 T = TypeVar("T") U = TypeVar("U") V = TypeVar("V") class WithLeft(Generic[T, U, V]): func: Callable[[T, U], V] left: T def __init__(self, func: Callable[[T, U], V], left: T) -> None: self.func = func self.left = left def __rshift__(self, right: U) -> V: return self.func(self.left, right) class WithRight(Generic[T, U, V]): func: Callable[[T, U], V] right: U def __init__(self, func: Callable[[T, U], V], right: U) -> None: self.func = func self.right = right def __rlshift__(self, left: T) -> V: return self.func(left, self.right) class Op(Generic[T, U, V]): func: Callable[[T, U], V] def __init__(self, func: Callable[[T, U], V]) -> None: self.func = func def __rlshift__(self, left: T) -> WithLeft[T, U, V]: return WithLeft(self.func, left) def __rshift__(self, right: U) -> WithRight[T, U, V]: return WithRight(self.func, right) if __name__ == "__main__": # 整数加法中缀运算符示例 print("定义整数加法中缀运算符 <<add>>") @Op def add(a: int, b: int) -> int: return a + b result = 12 <<add>> 44 print(f"{result} 等于预期的 {12 + 44}") # 函数组合中缀运算符示例 print("\n定义函数组合中缀运算符 <<compose>>") P = TypeVar("P") Q = TypeVar("Q") R = TypeVar("R") @Op def compose(left: Callable[[Q], P], right: Callable[[R], Q]) -> Callable[[R], P]: return lambda x: left(right(x)) from math import cos, log logcos: Callable[[float], float] = log <<compose>> cos print(f"{logcos(1)} 等于预期的 {log(cos(1))}")
关键修正点
- 明确泛型与函数类型的关联:给
Op、WithLeft、WithRight类的func属性添加Callable[[T, U], V]类型注解,让mypy能从被装饰的双参数函数自动推导泛型参数T(左参数类型)、U(右参数类型)、V(返回值类型)。 - 完善初始化方法的类型约束:每个类的
__init__方法都明确参数类型,确保实例化时类型匹配,避免模糊推断。 - 完全保留原有语法:业务代码的调用方式
left <<op>> right无需任何修改,保持原有易用性。
运行mypy --strict检查上述代码,所有类型错误都会消失,泛型参数能被正确推断。
内容的提问来源于stack exchange,提问作者Retired Writing Code for Fun
相关产品推荐
相关产品推荐

