如何在Python中实现类型安全的CRTP(奇异递归模板模式)?
在Python中用Mypy实现类型安全的奇异递归模板模式(CRTP)
直接把派生类作为泛型参数传入基类会触发Mypy报错,因为定义Derived的过程中,类对象还未完全创建,Mypy会识别出未定义的名称。下面是两种可行的解决方式:
方法一:使用字符串前向引用
通过字符串形式指定尚未定义的派生类,同时用TypeVar约束类型范围,保证类型安全:
from typing import Generic, TypeVar, cast # 定义TypeVar,限定T必须是GenericParent的子类 T = TypeVar("T", bound="GenericParent[T]") class GenericParent(Generic[T]): def do_something(self) -> T: # 用cast明确类型转换,避免Mypy警告 return cast(T, self) class Derived(GenericParent["Derived"]): def specific_method(self) -> None: print("Derived专属方法")
方法二:使用延迟注解(Python 3.10+)
导入__future__的annotations后,所有类型注解会自动作为字符串处理,无需手动加引号:
from __future__ import annotations from typing import Generic, TypeVar, cast T = TypeVar("T", bound="GenericParent[T]") class GenericParent(Generic[T]): def do_something(self) -> T: return cast(T, self) class Derived(GenericParent[Derived]): def specific_method(self) -> None: print("Derived专属方法")
验证类型安全性
可以用Mypy的reveal_type工具检查类型是否正确:
d = Derived() reveal_type(d.do_something()) # Mypy会输出:Revealed type is "Derived"
这样就能实现和C++/C#类似的类型安全CRTP,基类方法可以正确返回派生类类型,Mypy也能正常进行类型检查。
内容的提问来源于stack exchange,提问作者Alexidarex
相关产品推荐
相关产品推荐

