Допустим, у меня есть какой-то абстрактный Node
класс.Каждый узел должен принимать некоторые входные данные и создавать выходные данные, каждый из которых может быть другого типа.Чтобы упростить разработку, чтобы увидеть, что Node
совместимо с другими Node
, я хочу использовать подсказки типа, поэтому у меня есть:
T_In = TypeVar("T_In")
T_Out = TypeVar("T_Out")
class Node(Generic[T_In, T_Out]):
input_: T_In
output: T_Out
def __init__(self, input_: T_In):
self.input_ = input_
self.output = None
def prepare_output(self):
raise NotImplemented()
def get_output(self) -> T_Out:
return self.output
Пока все хорошо (этоконечно, не предназначенный для непосредственного создания).
Теперь у меня есть подкласс MapNode
, который принимает некоторую функцию, которая выполняет фактическое преобразование данных.Я хочу использовать сигнатуру функции для автоматического определения типов для класса Node
.Более конкретно, этот узел всегда принимает список некоторого типа (эквивалентный типу ввода функции) и создает список другого типа (тип вывода функции).Я попробовал следующее:
T_Lambda_In = TypeVar("T_Lambda_In")
T_Lambda_Out = TypeVar("T_Lambda_Out")
New_IT = TypeVar("New_IT", bound=List[T_Lambda_In])
New_OT = TypeVar("New_OT", bound=List[T_Lambda_Out])
class MapNode(Node[New_IT, New_OT]):
def __init__(self, input_, lambda_: Callable[[T_Lambda_In], T_Lambda_Out]):
super(Node, self).__init__(input_)
self.lambda_ = lambda_
def prepare_output(self):
self.output = [self.lambda_(obj) for obj in self.input_]
Функцией может быть, например:
def cast_int(val: str) -> int:
return int(val)
Я думал, что это должно генерировать подсказки типа:
node: MapNode[List[str], List[int]] = MapNode(["1", "2"], lambda_=cast_int)
Вместо этого PyCharm генерирует:
node: MapNode[Any, Any] = MapNode(["1", "2"], lambda_=cast_int)
Кажется, что использование типов в сигнатуре функции недостаточно для правильного разрешения «производных» типов T_Lambda_In
и T_Lambda_Out
.Любая помощь в исправлении этого будет принята с благодарностью!Кстати, я использую Python 3.6.