Следующий код прекрасно работает на PyCharm. Я добавил кейс complex
, чтобы сделать его более понятным.
В основном я извлек метод в обобщенный класс c, а затем использовал его в качестве миксина для каждого подкласса. Пожалуйста, используйте с особой осторожностью, так как это выглядит довольно нестандартно.
from typing import ClassVar, Generic, TypeVar, Callable
S = TypeVar('S', bound=complex)
class SomeMethodImplementor(Generic[S]):
RET_TYPE: ClassVar[Callable]
def some_method(self, some_input: str) -> S:
return self.__class__.RET_TYPE(some_input)
class SomeClass(SomeMethodImplementor[complex]):
RET_TYPE = complex
class SomeChildClass(SomeClass, SomeMethodImplementor[float]):
RET_TYPE = float
class OtherChildClass(SomeChildClass, SomeMethodImplementor[int]):
RET_TYPE = int
if __name__ == "__main__":
ret: complex = SomeClass().some_method("42")
ret2: float = SomeChildClass().some_method("42")
ret3: int = OtherChildClass().some_method("42")
print(ret, type(ret), ret2, type(ret2), ret3, type(ret3))
Если вы измените, например, с ret2: float
на ret2: int
, будет правильно отображена ошибка типа.
К сожалению, mypy отображает ошибки в этом случае (версия 0.770),
otherhint.py:20: error: Incompatible types in assignment (expression has type "Type[float]", base class "SomeClass" defined the type as "Type[complex]")
otherhint.py:24: error: Incompatible types in assignment (expression has type "Type[int]", base class "SomeClass" defined the type as "Type[complex]")
otherhint.py:29: error: Incompatible types in assignment (expression has type "complex", variable has type "float")
otherhint.py:30: error: Incompatible types in assignment (expression has type "complex", variable has type "int")
Первые ошибки могут быть "исправлены" написанием
RET_TYPE: ClassVar[Callable] = int
для каждого подкласса. Теперь ошибки уменьшаются до
otherhint.py:29: error: Incompatible types in assignment (expression has type "complex", variable has type "float")
otherhint.py:30: error: Incompatible types in assignment (expression has type "complex", variable has type "int")
, что в точности противоположно тому, что мы хотим, но если вы заботитесь только о PyCharm, это не имеет значения.