Тип базового класса в миксинах
У меня есть большой класс разбитый на миксины:
class MyObject(MyObjectFilesMixin, MyObjectProcessingMixin, ...):
def __init__(self, value):
self.value = self.preprocess(value)
Миксины такие:
class MyObjectFilesMixin:
def load_from_file(cls, filename):
return ...
Сейчас хочу добавить везде типизацию:
class MyObjectFilesMixin:
def load_from_file(cls, filename: str) -> MyObject:
return ...
class MyObjectProcessingMixin:
def preprocess(self: MyObject, value: bytes):
return value # логика опущена
def append(self: MyObject, other: MyObject):
self.value += other.value
Но это приводит к циклическим зависимостям. Конечно, можно создать какой-нибудь класс вида MyObjectBase (следуя принципу инверсии зависимостей), чтобы главный класс MyObject мог наследовать этот базовый, а миксины использовали его как тип аргумента/результата в методах, но это всё же корявый тип будет. Как это можно исправить??
Немного скучаю по заголовочным/исходным файлам C++
Ответы (2 шт):
у cls и self type hints не используют, так как и так понятно, что self это экземпляр объекта того класса, который вызывается, а cls это объект класса в котором определен метод данного класса(только не забудьте декоратор @classmethod)
Нашёл способ, как обойтись без дублирования кода, протоколов и т.п, DRY! Решение у меня простое:
from typing import TYPE_CHECKING, Type
if TYPE_CHECKING:
from my_object import MyObject
MO = Type('MyObject')
class MyObjectFilesMixin:
def load_from_file(cls: MO, filename: str) -> 'MyObject':
# Now I'm able to access all the methods of MyObject by cls
# with correct IDE support and MyPy checking
return ...
class MyObjectProcessingMixin:
def preprocess(self: 'MyObject', value: bytes):
return value # логика опущена
def append(self: 'MyObject', other: 'MyObject'):
self.value += other.value
Разве что теперь всплывает warning, видимо MyPy не ожидает получить ребёнка как тип у родителя:
Mypy: The erased type of self "Type[... MyObject]" is not a supertype of its class "Type[...MyObjectFilesMixin]"
Но это малая цена за то, чтобы методы и типы были видны и правильно поняты IDE и MyPy!