如何在Python中强制子类process方法返回类型符合泛型约束?
问题描述
我在代码中采用Service Object模式,定义了如下泛型抽象基类BaseService:
from abc import ABC, abstractmethod from typing import Generic, TypeVar T = TypeVar("T", contravariant=True) # input type R = TypeVar("R", covariant=True) # return type class BaseService(Generic[T, R], ABC): """Service object that strongly types its inputs and outputs.""" inputs: T def __init__(self, inputs: T): self.inputs = inputs @classmethod def execute(cls, inputs: T, **kwargs) -> R: instance = cls(inputs, **kwargs) return instance.process() @abstractmethod def process(self) -> R: """ Main method to be overridden; contains the business logic. """
其使用示例如下:
from typing import TypedDict class Inputs(TypedDict): foo: str class DoubleService(BaseService[Inputs, str]): def process(self): return self.inputs["foo"] * 2 DoubleService.execute({"foo": "bar"}) # returns "barbar"
我希望类型检查器能强制子类中process方法的返回类型符合约束,例如以下两种错误情况应被检测出来:
class Inputs(TypedDict): foo: str class InvalidOne(BaseService[Inputs, str]): def process(self) -> int: # wrong explicit return type # ... class InvalidTwo(BaseService[Inputs, str]): def process(self): return 1 # wrong implicit return type
请问是否有现有类型检查器(如Mypy、Pyright等)可以实现这一需求?
解决方案
Mypy和Pyright这两款主流类型检查器都能满足你的需求,具体表现如下:
Mypy
- 针对
InvalidOne这种显式声明错误返回类型的情况,会直接抛出类型不兼容错误,提示返回类型int与基类定义的str约束不符。 - 针对
InvalidTwo这种隐式返回类型错误的情况,只要开启--strict严格模式,就能自动推断出process方法的返回类型为int,并检测到与基类str约束的冲突,抛出错误提示。
- 针对
Pyright
- 默认配置下就能检测出
InvalidOne的显式返回类型错误。 - 对于
InvalidTwo的隐式返回类型问题,默认也能自动推断返回类型并识别冲突;若需要更严格的校验,可开启strictReturnTypes配置项强化约束。
- 默认配置下就能检测出
无需修改你的抽象基类代码,这两款工具都能很好地帮你强制子类process方法的返回类型符合基类的泛型约束。
内容的提问来源于stack exchange,提问作者tao_oat
相关产品推荐
相关产品推荐

