实例化一个TypeVar类型

时间:2019-03-25 20:04:43

标签: python python-3.x type-hinting

作为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无法实例化实际上是TypeVars的类(TPopMember)。我只想创建一个列表(Population),并带有几个默认初始化(TP)在TPopMembers中使用。我该怎么办?

我正在使用Python 3.7.2。

2 个答案:

答案 0 :(得分:2)

您没有意识到类型提示是提示。换句话说,根本不要认为它是一种类型。您无法实例化它们。

据您的评论我了解,您的意图是执行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)

输出:

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

您需要了解的是,如果您从Generic[T]派生一个类,则在创建类时需要使用T。在我的示例中,我创建一个虚拟对象并解析其类并启动它。通常我不会以这种方式编写,我可以将一个类作为参数传递给构造器以请求生成此特定类型的项目,因为参数本身与实例是不同的。也是一个Python对象。 (感谢切普纳的建议)

答案 1 :(得分:1)

您可以执行以下操作:

from typing import TypeVar, Generic, List, NewType
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, populationSize: int) -> None:
        obj = self.__orig_class__.__args__[0]
        self.__population = Population([obj() for _ in  range(populationSize)])

    @property
    def population(self):
        return self.__population

evolution = EvolutionaryAlgorithm[PopMember](100)
print(evolution.population)

可以在此处的实例中找到用于定义 Generic 类的类型:self.__orig_class__.__args__[0]

对于类方法,只需使用此 -> cls.__args__[0]