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
那么 Int32
和 Int64
在 PEP484 领域中将是相同的,但您可以通过使用社区维护的 typed-ast
module 查看代码的 AST(抽象语法树)来添加一些额外的检查。除了代码之外,该模块还解析类型 cmets,因此您可以阅读所使用的 exact 注释,从而获得 x
和 y
的一些额外类型信息。
而且,如果隐身不是第一要务,那么:
而不是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-ast
和 mypy
现在(2016 年)都处于非常活跃的开发阶段。并非一切都按预期工作,但据我所知,它们对于许多用例已经足够好,而且似乎没有其他选择。
【讨论】:
以上是关于PEP-484 具有自己类型的类型注释的主要内容,如果未能解决你的问题,请参考以下文章