如何为 Sequence[T] 提供泛型类型参数?

Posted

技术标签:

【中文标题】如何为 Sequence[T] 提供泛型类型参数?【英文标题】:How to provide generic type parameter to Sequence[T]? 【发布时间】:2017-12-06 11:13:59 【问题描述】:

我正在尝试在 Python 中创建一个存储 T 类型元素的列表,但是,我不知道如何为此类列表的实例指定具体类型。

对于非列表实例,实现非常清晰:

from typing import TypeVar, Generic

T = TypeVar("T")


class MyGenericType(Generic[T]):
    def __init__(self):
        self.value: T = None


generic_instance: MyGenericType[int] = MyGenericType()

最后一行按预期工作:它使T 成为int 的实例,然后我可以在其中存储这些值。

对于列表,我因此写了以下内容:

from typing import TypeVar, Sequence

T = TypeVar("T")


class MyGenericList(Sequence[T]):
    def __init__(self):
        self.store: Sequence[T] = []

    # abstract method implementations cut for brevity


generic_list: MyGenericList[int] = MyGenericList()

最后一行应该创建了一个存储 int 元素的列表,但是我的 IDE (PyCharm) 抱怨第一个左方括号:

“ABCMeta”类没有定义“__getitem__”,因此不能在其实例上使用“[]”运算符

显然它试图通过索引运算符访问列表元素,但是,我想在这个地方指定泛型类型。这是不可能的还是我做错了什么?

难道这只是一个 PyCharm 错误?这听起来确实类似于Python 3.5 Typing ABCMeta does not define '__getitem__',但我已经在运行 IDE 的 2017.1.4 版本,并且问题中提到的错误仅影响返回类型的提示(似乎)。

【问题讨论】:

我不知道 "self.value: T = None" 语法中 : 的含义。有人可以帮我指出一些文档以了解更多信息吗?很抱歉垃圾邮件 - 我糟糕的谷歌技能也没有帮助我获得任何有意义的搜索结果。 你看过他的检查器mypy-lang.org吗? @c0dec0de python.org/dev/peps/pep-0526 感谢@AshwiniChaudhary,这似乎是 python 3.x 特有的,我了解到我们可以像 go 和许多其他语言一样为变量设置显式类型。再次感谢。 【参考方案1】:

看起来我也必须从 Generic[T] 继承列表。我不知道为什么,我认为Sequence[T] 已经为我做到了。也许有人可以解释一下这方面的背景。

class MyGenericList(Generic[T], Sequence[T]):
    def __init__(self):
        self.store: Sequence[T] = []

根据关于泛型如何工作的原始注释,这似乎是 PyCharm 的一个错误,并且不需要从 Generic[T] 额外派生...

【讨论】:

看来你必须将Generic[T] 放入祖先中,即使其中一些继承了它。见MutableSequencetyping.pyi 我认为这是一个 PyCharm 错误——我无法使用 mypy 重现它。还有一个很小的可能性是,这可能部分是由于您使用了旧版本的 Python(它附带了旧版本的 typing.py)在某处导致了奇怪的交互,但很难说。对于上下文,PEP 484 用于指定所有用户定义的类型需要子类化 Generic[T],但后来出于人体工程学原因,当您对其他泛型类型进行子类化时,此限制被解除。也许这就是混淆的来源? 我也必须明确地从Generic[T] 派生出来,这对我来说也没有多大逻辑意义。 PyCharm 目前似乎在(通用)类型提示方面存在很多问题——它只是随机开始抱怨我的每个班级的每个__init__ 中的第一个提示成员分配“没有回报”,它希望他们返回我为该成员暗示的任何东西......可能会诉诸 JetBrains 来解决这个问题。

以上是关于如何为 Sequence[T] 提供泛型类型参数?的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 如何为泛型函数创建泛型类型别名?

如何为多个泛型类型使用关键字`where`? [复制]

Java泛型方法和构造函数

Swift2.0(17)泛型技术

当其中一个是本地引用时,如何为类型约束中的引用编写生命周期?

Kotlin 泛型