Python方法重写:派生类使用更具体参数的合规实现方案
解决方案:用泛型绑定Document与对应Paragraph类型
问题出在你的基类Document的from_paragraphs方法参数是Sequence[Paragraph],但子类缩小了参数范围,只接受Sequence[LegalParagraph]/Sequence[AcademicParagraph],这违反了里氏替换原则——当子类被当作基类使用时,无法处理基类方法能接受的所有输入(比如给LegalDocument传入普通Paragraph序列)。
要解决这个问题,我们可以通过泛型让Document类与它能处理的Paragraph子类绑定,既满足类型约束,又通过类型检查:
from abc import ABC, abstractmethod from typing import Sequence, TypeVar, Generic # 定义一个受限于Paragraph子类的类型变量 P = TypeVar('P', bound='Paragraph') class Document(ABC, Generic[P]): @classmethod @abstractmethod def from_paragraphs(cls, paragraphs: Sequence[P]) -> 'Document[P]': pass class LegalDocument(Document['LegalParagraph']): @classmethod def from_paragraphs(cls, paragraphs: Sequence['LegalParagraph']) -> 'LegalDocument': # 具体实现逻辑 return cls() class AcademicDocument(Document['AcademicParagraph']): @classmethod def from_paragraphs(cls, paragraphs: Sequence['AcademicParagraph']) -> 'AcademicDocument': # 具体实现逻辑 return cls() class Paragraph: def __init__(self, text: str): self.text = text class LegalParagraph(Paragraph): pass class AcademicParagraph(Paragraph): pass
关键说明:
- 用
TypeVar定义了一个类型变量P,它只能是Paragraph或其子类,确保类型安全。 Document继承Generic[P]成为泛型类,每个子类继承时指定对应的Paragraph子类(比如Document['LegalParagraph'])。- 基类的
from_paragraphs方法参数为Sequence[P],返回Document[P],子类实现时可以替换为具体的类型(比如Sequence[LegalParagraph]和LegalDocument)。这样类型检查器能正确识别每个子类的参数要求,同时不会违反里氏替换原则——因为此时LegalDocument是Document[LegalParagraph]的实例,而非Document[Paragraph],不会出现用基类类型引用子类后传入不兼容参数的情况。
内容的提问来源于stack exchange,提问作者malyvsen
相关产品推荐
相关产品推荐

