如何对类型为泛型基类的任何子类的变量进行类型提示?

问题描述 投票:0回答:1

我有两个链接的抽象基类,应该一起子类化。为了举一个最小的例子,我们假设它有一个类

TobeProcessed
,以及另一个类
Processor
,它对
TobeProcessed
类的实例执行一些处理。我用
Processor
类的类型作为类型参数创建了
Generic
TobeProcessed

from abc import ABC, abstractmethod
from typing import Generic, TypeVar


class TobeProcessed(ABC):
    pass


TobeProcessedType = TypeVar("TobeProcessedType", bound=TobeProcessed)


class Processor(ABC, Generic[TobeProcessedType]):
    @abstractmethod
    def process(self, to_be_processed: TobeProcessedType) -> None:
        pass

现在我有了这两个类的一些具体实现:

class TobeProcessedConcrete(TobeProcessed):
    pass


class ProcessorConcrete(Processor[TobeProcessedConcrete]):
    def process(self, to_be_processed: TobeProcessedConcrete) -> None:
        return None

最后,我有一个“包装”类,它有一个属性

processor
,它是
Processor
类的任何子类的实例。

class WrapperClass:
    processor: Processor

    def __init__(self, processor: Processor) -> None:
        self.processor = processor


processor = ProcessorConcrete()
wrapper = WrapperClass(processor=processor)

如果我用

mypy
--disallow-any-generics
(或
--strict
)检查这个,我会得到
WrapperClass
的两个错误,因为我省略了
Processor
的类型参数,这是有道理的。但是,如果我将
Processor
替换为
Processor[TobeProcessed]
,则会出现
wrapper = WrapperClass(processor=processor)
:

行错误

Argument "processor" to "WrapperClass" has incompatible type "ProcessorConcrete"; expected "Processor[TobeProcessed]"
.

有没有一种方法可以做到这一点而不会出现错误,并且不会使

mypy
不那么严格?

python-3.x generics mypy type-hinting abstract-base-class
1个回答
0
投票

应该是

Processor[TobeProcessedType]

from abc import ABC, abstractmethod
from typing import Generic, TypeVar


class TobeProcessed(ABC):
    pass


TobeProcessedType = TypeVar("TobeProcessedType", bound=TobeProcessed)


class Processor(ABC, Generic[TobeProcessedType]):
    @abstractmethod
    def process(self, to_be_processed: TobeProcessedType) -> None:
        pass


class TobeProcessedConcrete(TobeProcessed):
    pass


class ProcessorConcrete(Processor[TobeProcessedConcrete]):
    def process(self, to_be_processed: TobeProcessedConcrete) -> None:
        return None


class WrapperClass(Generic[TobeProcessedType]):
    processor: Processor[TobeProcessedType]

    def __init__(self, processor: Processor[TobeProcessedType]) -> None:
        self.processor = processor


processor = ProcessorConcrete()
wrapper = WrapperClass(processor=processor)
© www.soinside.com 2019 - 2024. All rights reserved.