Как я могу создать класс универсального типа? - PullRequest
0 голосов
/ 15 октября 2019

Мне нужно создать универсальный класс с использованием typing.TypeVar, а затем создать в этом классе объекты универсальных типов.

Итак, мне нужно что-то вроде этого

from typing import TypeVar, Generic

T = TypeVar('T')

class MyClass(Generic[T]):
    def create(self) -> T:
        created_obj = T() # Exception
        return created_obj

my_list_class = MyClass[list]()
new_list = my_list_class.create()

my_dict_class = MyClass[dict]()
new_dict = my_dict_class.create()

Итак,Я ожидал, что это сработает, но возникло исключение, что вы не можете вызвать TypeVar.

1 Ответ

1 голос
/ 15 октября 2019

Помните, что подсказки типов полностью игнорируются во время выполнения. Таким образом, это означает, что даже если средство проверки типов определит, что какой-то конкретный экземпляр вашего класса имеет тип MyClass[List[Any]], он все равно будет просто MyClass во время выполнения. В частности, каждое вхождение T будет , а не автоматически каким-либо образом заменяться связанным типом.

Вместо этого вам нужно будет указать нужный тип во время выполнения самостоятельно:

from typing import TypeVar, Generic, Type

T = TypeVar('T')

class MyClass(Generic[T]):
    def __init__(self, type_factory: Type[T]) -> None:
        self._type_factory = type_factory

    def create(self) -> T:
        return self._type_factory()

# Note: we no longer need to explicitly fill in the generic params, since the
# type checker now has enough info to infer this for us.
my_list_class = MyClass(list)
new_list = my_list_class.create()

my_dict_class = MyClass(dict)
new_dict = my_dict_class.create()

Если вы хотите, чтобы ваш код был еще более точным и немного лучше обобщенным, вы могли бы иметь тип type_factory быть Callable[[], T] вместо Type[T].

...