#python #mypy #python-typing
Вопрос:
У меня есть базовый класс, такой как follow:
class BaseClass:
@classmethod
def create(cls, arg1: str) -> BaseClass:
instance = cls(arg1)
return instance
И производный класс, подобный этому:
class DerivedClass(BaseClass):
def __init__(self, arg: str) -> None:
self.arg = arg
Теперь, когда я это делаю
data: DerivedClass = DerivedClass.create('first arg)
mypy выдает следующую ошибку:
"BaseClass" cannot be assigned to declared type "DerivedClass"
"BaseClass" is incompatible with "DerivedClass"
Как я решаю эту проблему, используя typing.cast
data: DerivedClass = cast(
DerivedClass,
DerivedClass.get(derived_class_instance)
)
Как я должен решить эту проблему без использования typing.cast
Ответ №1:
Вы можете перейти BaseClass
на это:
T = TypeVar("T")
from typing import TypeVar, Type
class BaseClass:
@classmethod
def get(cls: Type[T], instance: T) -> T:
return instance
Это заставляет instance
быть того типа, для которого get
вызывается метод класса. Поэтому BaseClass.get
берет a BaseClass
и возвращает a BaseClass
, в то время DerivedClass.get
как берет a DerivedClass
и возвращает a DerivedClass
. Запуск mypy
приводит к:
Success: no issues found in 1 source file
Комментарии:
1. Большое спасибо, это прекрасно работает. но когда я использую cls для создания экземпляра в classmethod, он говорит
BaseClass cannot be instantiated
. Пожалуйста, проверьте правки. Извините, что изменил вопрос.2. В таком случае
mypy
это правильно. Вы предполагаете, что все возможноеcls
может быть создано с помощью astr
. Но толькоDerivedClass
может иBaseClass
не может, поэтомуBaseClass.create("abc")
произошла бы ошибка во время выполнения. Вы понимаете, почему mypy отклоняет вашу программу? @wrufesh3. Когда cls другие свойства, к которым мы пытаемся получить доступ в базовом классе, чем мы получаем ошибку, как
xyz
атрибут не определен. в противном случае я сейчас не получаю никаких ошибок. также добавлениеT = TypeVar("T", bound=BaseClass)
также решает проблему атрибутов.