Python多泛型Protocol双向依赖下的兼容性实现方案咨询
可行方案
存在可实现该需求的合法写法,核心通过前向类型引用处理双向Protocol的依赖问题,主流Python类型检查器(mypy、pyright)均支持该语法。
完整实现代码
from typing import TypeVar, Protocol, Generic from dataclasses import dataclass # 用字符串前向引用声明TypeVar的边界,规避定义顺序问题 ExprT = TypeVar("ExprT", bound="ExprProto") VarT = TypeVar("VarT", bound="VarProto[ExprT]") class VarProto(Protocol[ExprT]): def __add__(self, expr: ExprT) -> ExprT: ... class ExprProto(Protocol[VarT, ExprT]): def __add__(self, x: VarT) -> ExprT: ... @dataclass class CompatibleThings(Generic[VarT, ExprT]): x: VarT expr: ExprT
验证示例
你可以用下面的实际实现类测试类型校验,均能正常通过:
# 实际业务实现类 class MyVar: def __init__(self, val: str): self.val = val def __add__(self, expr: "MyExpr") -> "MyExpr": return MyExpr(f"{self.val} + {expr.val}") class MyExpr: def __init__(self, val: str): self.val = val def __add__(self, x: MyVar) -> "MyExpr": return MyExpr(f"{self.val} + {x.val}") # 类型校验正常通过 pair = CompatibleThings[MyVar, MyExpr](x=MyVar("a"), expr=MyExpr("b")) # 相加操作也会被正确识别类型 new_expr = pair.x + pair.expr
核心要点
- 两个Protocol互相依赖时,其中一个在定义阶段另一个还未完成声明,用字符串形式的前向引用作为TypeVar的bound参数即可解决顺序问题。
- 泛型参数绑定对应Protocol的边界后,即可实现双向的类型约束,保证实现类符合协议要求。
内容的提问来源于stack exchange,提问作者user17425419
相关产品推荐
相关产品推荐

