实例化一个 TypeVar 类型

Jup*_*ter 6 python type-hinting python-3.x

作为 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)])
Run Code Online (Sandbox Code Playgroud)

显然,Python 无法实例化实际上是 TypeVars 的类(TPopMember)。我只是想创建一个列表(人口),其中有几个默认初始化(在 Python 中你怎么说?)TPopMembers。我应该怎么做?

我正在使用 Python 3.7.2。

adr*_*tam 7

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

正如我从您的评论中了解到的,您的意图是做 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)
Run Code Online (Sandbox Code Playgroud)

输出:

EA([Pop(49), Pop(94), Pop(24), Pop(73), Pop(66)])
Run Code Online (Sandbox Code Playgroud)

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

  • 不需要将 `PopMember` 的实例传递给 `__init__`,只需访问它的 `__class__` 属性。定义`__init__(self, member_class: Type[PopMember], ...)`,然后传递`PopMember` 本身(或`PopMember` 的任何子类)。 (2认同)