实例化一个 TypeVar 类型 [英] Instantiate a type that is a TypeVar

查看:44
本文介绍了实例化一个 TypeVar 类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

作为一个 C++ 程序员,下面的代码对我来说似乎很自然,但它不能运行:

As a C++ programmer the following code seems very natural to me but it doesn't run:

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).我只是想创建一个列表(人口),其中有几个默认初始化(在 Python 中你怎么说?)TPopMembers.我应该怎么做?

Apparently Python isn't able to instantiate classes (the TPopMember) that are actually TypeVars. I simply want to create a list (Population) with a couple of default initialized (how do you say that in Python?) TPopMembers. How should I go about this?

我使用的是 Python 3.7.2.

I'm using Python 3.7.2.

推荐答案

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

You didn't realize that type hint is a hint. In other words, don't think it is a type at all. You can't instantiate them.

我从您的评论中了解到,您的意图是做 C++ 模板允许您做的事情.所以这是我实现这一目标的方法:

As I understand from your comment, your intention is doing what C++ template allows you to do. So here is my way to achieve that:

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 对象.(感谢chepner的建议)

What you have to understand is that, if you derived a class from Generic[T], you need to use T some how when you create your class. In my example I create a dummy object and resolve its class and initiate it. Normally I would not write in this way, I can just throw in a class as parameber pass in a class to the constructor to request to generate items of this particular type because class itself, distinct from an instance of it, is also a Python object. (thanks chepner for the suggestion)

这篇关于实例化一个 TypeVar 类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆