#python #type-hinting #typing
Вопрос:
У меня есть функция, которая формирует список определенных экземпляров класса, допустим, это будет тип вывода list[SomeClass]
.
Тип выходного класса может отличаться в зависимости от данных (например, это может быть list[ClassA]
, list[ClassB]
list[ClassC]
, и т.д.).
Я пытаюсь передать этот список и лямбда — функцию в качестве аргументов в другой класс . Цель последнего класса состоит в том, чтобы разделить аргумент списка на два отдельных списка на основе этой лямбда-функции. Так что в основном то, что мне нужно, это:
def func_A(cls_instance: some_cls) -gt; list[some_cls]: ..... ..... return list[some_cls] class DividerClass() def __init__(list_of_classes: list[Object], func: Callable): self.list_of_classes = list_of_classes self.result_list_1 = [] self.result_list_2 = [] def divide(): for item in self.list_of_classes: if func(item): self.result_list_1.append(item) else: self.result_list_2.append(item) return self.result_list_1, self.result_list_2 if __name__ == '__main__': list_1 = func_A(SomeClass()) -gt; list[SomeClass] list_2 = func_A(YetAnotherClass()) -gt; list[YetAnotherClass] result_1_a, result_1_b = DividerClass(list_1, lambda_func).divide() -gt; tuple[list[SomeClass],list[SomeClass]] resule_2_a, result_2_b = DividerClass(list_2, lambda_func).divide() -gt; tuple[list[YetAnotherClass],list[YetAnotherClass]]
Но вместо того, чтобы получать такие результаты, как:
-gt; tuple[list[SomeClass],list[SomeClass]] -gt; tuple[list[YetAnotherClass],list[YetAnotherClass]]
У меня есть такой вывод:
-gt; tuple[list, list] -gt; tuple[list, list]
Итак, вопрос в том, как заставить компилятор/IDE знать тип класса внутри списка и выводить тип списка классов на основе входного аргумента?
Ответ №1:
Используется typing.Generic
для указания того, что в различных подписях будет использоваться произвольный, но фиксированный тип.
Что-то вроде
from typing import TypeVar, Tuple, Generic T = TypeVar('T') def func_A(cls_instance: T) -gt; list[T]: ... class DividerClass(Generic[T]) def __init__(self, list_of_classes: list[T], func: Callable[[T],list[T]]): self.list_of_classes = list_of_classes self.result_list_1 = [] self.result_list_2 = [] self.func = func def divide(self) -gt; Tuple[list[T], list[T]]: for item in self.list_of_classes: if self.func(item): self.result_list_1.append(item) else: self.result_list_2.append(item) return self.result_list_1, self.result_list_2
Комментарии:
1. Большое спасибо. Это, кажется, решает мою проблему. Но какова цель установки функции as
Callable[[T],list[T]])
. Это что-нибудь меняет?2.
Callable
само по себе означает , что вы могли бы передать что-то вродеlambda x, y: (x-y)/y
, но это было бы несовместимо с тем, какself.func
на самом деле вызывается .