Это пример того, чего я пытаюсь достичь:
Код: Выделить всё
#abstract_file_builder.py
from abc import ABC, abstractmethod
from typing import Generic, MutableSequence, TypeVar
from mymodule.type_a_file_builder import TypeARow
from mymodule.type_b_file_builder import TypeBRow
GenericRow = TypeVar("GenericRow", TypeARow, TypeBRow)
class AbstractFileBuilder(ABC, Generic[GenericRow]):
...
@abstractmethod
def generate_rows(
self,
) -> MutableSequence[GenericRow]:
pass
Код: Выделить всё
#type_a_file_builder.py
from typing import Any, MutableSequence
from mymodule.abstract_file_builder import AbstractFileBuilder
TypeARow = MutableSequence[Any]
class TypeAFileBuilder(AbstractFileBuilder[TypeARow]):
...
def generate_rows(
self,
) -> MutableSequence[TypeARow]:
... # Code logic for TypeA
return rows
Код: Выделить всё
#type_b_file_builder.py
from typing import MutableSequence, Union
from mymodule.abstract_file_builder import AbstractFileBuilder
TypeBRow = MutableSequence[Union[int, float]]
class TypeBFileBuilder(AbstractFileBuilder[TypeBRow]):
...
def generate_rows(
self,
) -> MutableSequence[TypeBRow]:
... # Code logic for TypeB
return rows
Я знаю, что могу использовать переменную TYPE_CHECKING, чтобы избежать импорта во время выполнения, но это похоже на исправление, а не на хорошее решение.
Еще одна вещь, которая может решить проблему, — это определить псевдонимы типов в абстрактном классе, но это разрушило бы всю цель создания абстрактный класс и не нужно знать, что реализовано ниже.
Однако я не уверен, смогу ли я создать какую-либо форму псевдонима «абстрактного» типа внутри Abstract_file_builder.py файл, а затем объявить типы TypeARow и TypeBRow как дочерние элементы этого абстрактного типа.
Должен отметить, что решение должно работать как минимум с Python 3.9. Если он поддерживает версии до 3.7, это будет лучше, но не обязательно.
Подробнее здесь: https://stackoverflow.com/questions/775 ... ract-class