Советы по типу Python: заставить вывод обобщенного типа работать с наследованием - PullRequest
0 голосов
/ 24 мая 2018

Допустим, у меня есть какой-то абстрактный 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.

...