Python 3.6 泛型类型提示

Posted

技术标签:

【中文标题】Python 3.6 泛型类型提示【英文标题】:Python 3.6 Generic Type Hints 【发布时间】:2019-02-14 18:36:10 【问题描述】:

我正试图围绕泛型类型提示。阅读 PEP 483 中的this section,我的印象是在

SENSOR_TYPE = TypeVar("SENSOR_TYPE")
EXP_A = Tuple[SENSOR_TYPE, float]
class EXP_B(Tuple[SENSOR_TYPE, float]):
    ...

EXP_AEXP_B 应该标识相同的类型。然而,在 PyCharm #PC-181.4203.547 中,只有 EXP_B 可以按预期工作。经过调查,我注意到EXP_B 有一个__dict__ 成员,而EXP_A 没有。

这让我想知道,这两种类型定义实际上是同义词吗?

编辑:我最初的目标是设计一个泛型类 EXP 的 2 元组,其中第二个元素始终是 float 并且第一个元素类型是可变的。我想按如下方式使用这个泛型类的实例

from typing import TypeVar, Tuple, Generic

T = TypeVar("T")


class EXP_A(Tuple[T, float]):
    ...


EXP_B = Tuple[T, float]


V = TypeVar("V")


class MyClass(Generic[V]):
    def get_value_a(self, t: EXP_A[V]) -> V:
        return t[0]

    def get_value_b(self, t: EXP_B[V]) -> V:
        return t[0]


class StrClass(MyClass[str]):
    pass


instance = "a", .5

sc = StrClass()
a: str = sc.get_value_a(instance)
b: str = sc.get_value_b(instance)

(PEP 484 中的The section on user defined generic types 将EXP 的定义描述为等同于我原始代码示例中的EXP_B。)

问题是PyCharm抱怨instance作为参数的类型:

Expected type EXP (matched generic type EXP[V]), got Tuple[str, float] instead`. With `EXP = Tuple[T, float]` instead, it says: `Expected type 'Tuple[Any]' (matched generic type Tuple[V]), got Tuple[str, float] instead.

【问题讨论】:

你能举一个EXP_A 没有按预期工作的例子吗? @Aran-Fey 在另一个文件中导入EXP_AEXP_B 以像class NewClassA(EXP_A[int]): ...class NewClassB(EXP_B[int]): ... 一样使用它们时,PyCharm 抱怨EXP_A 之后的第一个左方括号。它说Cannot find reference '[' in 'function | function',但EXP_B没有问题。 好吧,EXP_AEXP_B 都不是泛型,所以写 EXP_A[int] 是没有意义的。你不会指望Tuple[SENSOR_TYPE, float][int] 工作,对吗?我不知道你为什么要从Tuple 继承;你确定你正确使用了typing 模块吗...? @Aran-Fey this section 在 PEP 483 中说 Table = Dict[int, T] 通用的。情况与EXP_A 相同。此外,PEP 484 中的 this section 表示 class MyIter(Iterator[T]): ... 等同于 generic class MyIter(Iterator[T], Generic[T]): ...,这似乎与 EXP_B 相同。回答您的问题: 1. 实际上,我假设 int 填充类型变量。 2. 这就是我想知道的。 我怀疑但无法确认 mypy、Pycharm 和其他类型检查器目前不能非常优雅地处理复杂的类型别名扩展。无论如何,我建议您尝试在 Pycharm 的问题跟踪器上提交问题。可能还值得检查一下您在使用 mypy 时是否有相同的行为——如果是这样,我会尝试在 mypy 的问题跟踪器上发布问题或尝试在 Python typing gitter chat 上提问。我认为 *** 上的任何人都无法回答这个问题(以及您之前的问题) 【参考方案1】:

我听从了@Michael0c2a 的建议,前往 python 输入 gitter 聊天室,并在那里提出了问题。答案是这个例子是正确的。 从这个,我遵循那个

    EXP_AEXP_B 确实定义了同一种类型 从构建 #PC-182.4323.49 开始的 PyCharm 不能很好地处理泛型类型注释。

【讨论】:

以上是关于Python 3.6 泛型类型提示的主要内容,如果未能解决你的问题,请参考以下文章

TS泛型类、泛型接口、泛型函数

JAVA中的泛型类是啥东西?

java中如何得到泛型参数的class?

Kotlin泛型 ① ( 泛型类 | 泛型参数 | 泛型函数 | 多泛型参数 | 泛型类型约束 )

Java泛型

java泛型——泛型类泛型方法泛型接口