Создание экземпляра типа TypeVar - PullRequest
0 голосов
/ 25 марта 2019

Как программисту на C ++ следующий код кажется мне очень естественным, но он не запускается:

from typing import TypeVar, Generic, List, NewType

TPopMember = TypeVar('TPopMember')
Population = NewType('Population', List[TPopMember])
class EvolutionaryAlgorithm(Generic[TPopMember]):
    def __init__(self, populationSize: int) -> None:
        # The following raises TypeError: 'TypeVar' object is not callable
        self.__population = Population([TPopMember() for _ in range(populationSize)])

Очевидно, что Python не может создавать экземпляры классов (TPopMember), которые на самом деле являются TypeVars. Я просто хочу создать список (Population) с парой инициализированных по умолчанию (как вы говорите это в Python?) TPopMembers. Как мне поступить об этом?

Я использую Python 3.7.2.

1 Ответ

2 голосов
/ 25 марта 2019

Вы не поняли, что подсказка типа является подсказкой .Другими словами, не думайте, что это вообще тип.Вы не можете создать их экземпляр.

Как я понимаю из вашего комментария, вы намерены делать то, что позволяет шаблон C ++.Вот мой способ достижения этого:

from typing import TypeVar, Generic, List, NewType, Type
import random

class PopMember:
    def __init__(self):
        self.x = random.randint(0, 100)
    def __repr__(self):
        return "Pop({})".format(self.x)

TPopMember = TypeVar("TPopMember")
Population = NewType('Population', List[TPopMember])

class EvolutionaryAlgorithm(Generic[TPopMember]):
    def __init__(self, member_class: Type[TPopMember], populationSize: int) -> None:
        self.__population = Population([member_class() for _ in range(populationSize)])
    def __repr__(self):
        return "EA({})".format(self.__population)

x = EvolutionaryAlgorithm(PopMember, 5)
print(x)

output:

EA([Pop(49), Pop(94), Pop(24), Pop(73), Pop(66)])

Что вы должны понять, так это то, что если вы получили класс из Generic[T], вам необходимоиспользуйте T как, когда вы создаете свой класс.В моем примере я создаю фиктивный объект, разрешаю его класс и инициирую его.Обычно я не пишу таким образом, я могу просто добавить класс как параметр передать класс конструктору для запроса на генерацию элементов этого конкретного типа, потому что сам класс, отличный от его экземпляра, такжеобъект Python.(спасибо Чепнер за предложение)

...