PEP-484 具有自己类型的类型注释

Posted

技术标签:

【中文标题】PEP-484 具有自己类型的类型注释【英文标题】:PEP-484 Type Annotations with own types 【发布时间】:2016-10-26 14:45:36 【问题描述】:

PEP-484 为类型注释提供语义。 这些非常适合 a) 文档和 b) IDE 帮助。它们不太适合代码优化。

例如,很遗憾,不能将 PEP 484 注释与 Cython 一起使用 https://groups.google.com/d/msg/cython-users/DHcbk78rDec/6-b5XtCRGBEJ

或使用 Numba,后者使用自己的注释格式,以字符串的形式,如“float64(int32, int32)” http://numba.pydata.org/numba-doc/0.24.0/reference/types.html

我如何在 PEP 484 的框架内使用我自己的类型? 我明确不想破坏 PEP-484 语义,而是用附加信息扩充现有类型 对我自己的类型检查器可见,但对任何符合 PEP-484 的类型检查器或 IDE 都不可见。

以下内容是否会在 PEP-484 语义中被解释为 List[int]?

class Int32(int): pass
x = [1]   # type: List[Int32]

像这样更花哨的类型怎么样?

def combine(typeA, typeB):
    class X(typeA, typeB): pass
    return X

class Metre(): pass

# is y an 'int' to PEP-484 typecheckers?
y = 1 # type: combine(Int32, Metre)

对于使用类型提示的库有什么建议,包括类型解析和类型检查?

【问题讨论】:

numpy 和 484 上的类似问题 - ***.com/q/35673895/901925 我对研究不同的类型系统很感兴趣。我想拥有一个具有 Shen (shenlanguage.org/learn-shen/types/types_sequent_calculus.html) 灵活性的系统,并且能够定义自己的类型和键入规则。第一步是为测量单位构建一个静态检查器。 484 类型的语义非常诱人,b/c 非常灵活,例如我(希望)表示一个变量是 Int32 类型,同时具有维度米。优化器对 int32 感到满意,检查了物理单位,并且 gui 将 y 识别为 int。 很好的链接到 numpy 问题,这是正确的长期方向,我也喜欢 datashape 项目。首先,我更感兴趣的是打字方面如何在 484 上下文中处理我自己的类型以及如何从程序中解析类型信息。当然,我希望未来外部库能够最大程度地共享类型注解。 【参考方案1】:

从 Python 3.5 开始,我们不仅有PEP 483、PEP 484,还有实现它的typing module。

为了完全理解,您可能需要通读这 3 个文档。但对于您的具体情况,简短的回答是,在 PEP484 领域中,您可以通过 4 种方式使用自己的类型:

    只需使用自己的类型进行注释, 创建type aliases, 使用NewType,或 使用own generic types

如果你的追求高于一切:

其他信息对我自己的类型检查器可见,但对任何符合 PEP-484 的类型检查器均不可见

那么第二种方法就是这样。如果你这样做:

Int32 = int
Int64 = int

x = 0 # type: Int32
y = 0 # type: Int64

那么 Int32Int64 在 PEP484 领域中将是相同的,但您可以通过使用社区维护的 typed-ast module 查看代码的 AST(抽象语法树)来添加一些额外的检查。除了代码之外,该模块还解析类型 cmets,因此您可以阅读所使用的 exact 注释,从而获得 xy 的一些额外类型信息。


而且,如果隐身不是第一要务,那么:

而不是class Int32(int): pass,我宁愿使用typing.NewType('Int32', int),并且

我会使用typing.Union[Int32, Metre],而不是combine(Int32, Metre)

Int32 = typing.NewType('Int32', int)

class Metre:
    pass

x = [Int32(1)]  # type: List[Int32]
y = Int32(1) # type: typing.Union[Int32, Metre]

print(x[0] + 1) # ok, since Int32 is still int
y = Metre() # ok, since y can be Int32 or Metre

在上面的代码上,你可以运行社区维护的static type-checker mypy


typed-astmypy 现在(2016 年)都处于非常活跃的开发阶段。并非一切都按预期工作,但据我所知,它们对于许多用例已经足够好,而且似乎没有其他选择。

【讨论】:

以上是关于PEP-484 具有自己类型的类型注释的主要内容,如果未能解决你的问题,请参考以下文章

PEP 484:类型提示的专有类型

python 3.5代码中的变量需要类型注释

如何使用类型注释在 Python 中注释可变参数?

在 Python 中注释“文件类型”的正确方法

使用 python 2 类型注释指定实例变量的类型

如何在 PEP484 之后的方法参数中设置与类相同的类型? [复制]