Вот мой фрагмент кода. Интересно, какой возвращаемый тип использовать для метода классов create обоих заводских классов. Я бы не хотел использовать Union[Model1, Model2], если это возможно.

T = typing.TypeVar("T", bound="BaseModel")


@dataclass
class BaseModel(object):
    pass


@dataclass
class Model1(BaseModel):
    pass


@dataclass
class Model2(BaseModel):
    pass


class ModelFactory(ABC):
    @classmethod
    @abstractmethod
    def create(cls) -> T:
        pass


class Model1Factory(ModelFactory):
    @classmethod
    def create(cls) -> T:
        return Model1()


class Model2Factory(ModelFactory):
    @classmethod
    def create(cls) -> T:
        return Model2()

m1factory = Model1Factory()
m1 = m1factory.create()

Ошибка, которую я получаю от mypy:

type_hint.child_class_return_self.2.py:32: error: Incompatible return value type (got "Model1", expected "T")
type_hint.child_class_return_self.2.py:37: error: Incompatible return value type (got "Model2", expected "T")
type_hint.child_class_return_self.2.py:41: error: Need type annotation for 'm1'
0
randomness2077 5 Окт 2020 в 20:49

2 ответа

Лучший ответ

Я думаю, вам просто нужно включить Generic в уравнение, чтобы mypy мог принимать различные типы возвращаемых значений:

from abc import ABC
from typing import Generic, TypeVar


T = typing.TypeVar("T", bound="BaseModel")


@dataclass
class BaseModel(object):
    pass


@dataclass
class Model1(BaseModel):
    pass


@dataclass
class Model2(BaseModel):
    pass


class ModelFactory(Generic[T], ABC):
    @classmethod
    @abstractmethod
    def create(cls) -> T:
        pass


class Model1Factory(ModelFactory[Model1]):
    @classmethod
    def create(cls) -> Model1:
        return Model1()


class Model2Factory(ModelFactory[Model2]):
    @classmethod
    def create(cls) -> Model2:
        return Model2()


m1factory = Model1Factory()
m1 = m1factory.create()
1
star99ers 5 Окт 2020 в 18:04

Согласно шпаргалке по mypy, вам следует выбрать Union[Model1, Model2], но если этого вы хотите избежать, следующий лучший кандидат - это тип Any.

0
amsh 5 Окт 2020 в 18:06