如何基于子类为基类公共请求方法设置独立的type hint类型注解
实现方案
使用泛型可以完美实现该需求,不需要子类重写方法逻辑,仅需声明对应返回类型即可,完整实现如下:
from typing import TypeVar, Generic, ClassVar, Any, TypeDict # 定义绑定Response基类的类型变量,限定泛型仅能传入Response的子类 T = TypeVar('T', bound='Response') class Response(TypeDict): ... class FooResponse(Response): ... class BarResponse(Response): ... # 基类声明为泛型类 class Request(Generic[T]): # 类变量存储子类对应的返回类型 response_cls: ClassVar[type[T]] @classmethod def make_request(cls, args: Any) -> T: # 基类统一实现所有逻辑,子类不需要重复编写 raw_resp = execute_db_query(cls, args) return cls.response_cls(**raw_resp) # 子类仅需指定泛型参数和对应的返回类,无需重写方法 class FooRequest(Request[FooResponse]): response_cls = FooResponse class BarRequest(Request[BarResponse]): response_cls = BarResponse
调用时类型检查器(mypy/pyright)会自动识别返回值类型:
# foo_resp 会被自动推导为FooResponse类型 foo_resp = FooRequest.make_request(args={}) # bar_resp 会被自动推导为BarResponse类型 bar_resp = BarRequest.make_request(args={})
如果你的场景确实不需要基类统一实例化返回对象,想要仅重写方法签名,也可以在子类中使用@override注解仅声明方法签名,实际运行时仍然调用基类实现:
from typing import override class FooRequest(Request): @override @classmethod def make_request(cls, args: Any) -> FooResponse: ...
不过该方案需要基类返回的对象实际类型和子类声明的返回类型完全匹配,否则类型检查会出现误判,更推荐第一种泛型类的实现方案。
内容的提问来源于stack exchange,提问作者kiabso
相关产品推荐
相关产品推荐

