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_A
和 EXP_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_A
和EXP_B
以像class NewClassA(EXP_A[int]): ...
和class NewClassB(EXP_B[int]): ...
一样使用它们时,PyCharm 抱怨EXP_A
之后的第一个左方括号。它说Cannot find reference '[' in 'function | function'
,但EXP_B
没有问题。
好吧,EXP_A
和 EXP_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_A
和 EXP_B
确实定义了同一种类型
从构建 #PC-182.4323.49 开始的 PyCharm 不能很好地处理泛型类型注释。
【讨论】:
以上是关于Python 3.6 泛型类型提示的主要内容,如果未能解决你的问题,请参考以下文章