如何在python 3.6中使用类型提示?

时间:2016-12-28 06:49:32

标签: python python-3.x type-hinting python-3.6 mypy

我注意到python 3.5和python 3.6增加了许多关于静态类型检查的功能,所以我尝试使用以下代码(在python 3.6中,稳定版本)。

from typing import List

a: List[str] = []
a.append('a')
a.append(1)
print(a)

让我感到惊讶的是,虽然1list附加到Pycharm只应包含字符串,但python没有给我错误或警告。 mypy检测到了类型错误,并给了我一个关于它的警告,但它并不明显,并且没有在输出控制台中显示,我害怕有时候我可能会错过它。我想要以下效果:

  1. 如果我显然使用了如上所示的错误类型,请抛出警告或错误。
  2. 如果编译器无法可靠地检查我使用的类型是对还是错,请忽略它。
  3. 这可能吗?也许a: List[str]可以做到这一点,但我更喜欢使用python-3.6-style类型检查(如# type List[str])而不是mypy中使用的注释样式(如Alamofire.download(urlString).responseData { response in print("Temporary URL: \(response.temporaryURL)") } ) 1}}。我很好奇是否在原生python 3.6中有一个开关来实现我上面提到的两点。

3 个答案:

答案 0 :(得分:28)

类型提示完全被Python运行时忽略,并且仅由第三方工具(如mypy和Pycharm的集成检查器)进行检查。还有一些鲜为人知的第三方工具使用类型注释在编译时或运行时进行类型检查,但大多数人使用mypy或Pycharm的集成检查器AFAIK。

事实上,我实际上怀疑在可预见的未来,类型搜索将永远集成到Python中 - 请参阅“非目标”#39; PEP 484(引入类型注释)和PEP 526(引入变量注释)的部分,以及Guido的评论here

我个人很高兴将类型检查与Python更强大地集成在一起,但似乎整个Python社区都没有准备好或愿意做出这样的改变。

最新版本的mypy应该理解Python 3.6变量注释语法和注释样式语法。实际上,变量注释基本上是Guido的想法(Guido目前是mypy团队的一部分) - 基本上,mypy和Python中的类型注释的支持几乎同时开发。

答案 1 :(得分:18)

  

这可能吗?也许mypy可以做到,但我更喜欢使用Python-3.6风格的类型检查(如a: List[str])而不是mypy中使用的注释风格(如# type List[str])。我很好奇是否在原生python 3.6中有一个开关来实现我上面提到的两点。

Python不会为你做这件事;你可以使用mypy进行类型检查(PyCharms内置检查器也应该这样做)。除此之外,mypy不限制您只键入注释# type List[str],您可以像在Python 3.6中那样使用变量注释,因此a: List[str]同样运作良好。

由于版本为mypy,因为版本是新鲜的,您需要安装typed_ast并使用mypy--fast-parser执行--python-version 3.6 {{} 3}}。这可能会很快改变,但现在你需要它们才能顺利运行

现在不需要

更新: --fast-parser--python-version 3.6

执行此操作后,mypy会检测到a: List[str]上第二个操作的不兼容性。假设您的文件名为tp_check.py,并带有语句:

from typing import List

a: List[str] = []
a.append('a')
a.append(1)
print(a)

使用上述参数运行mypy(您必须先pip install -U typed_ast):

python -m mypy --fast-parser --python-version 3.6 tp_check.py

发现错误:

tp_check.py:5: error: Argument 1 to "append" of "list" has incompatible type "int"; expected "str"

如前所述在许多其他关于使用Python 的类型提示的答案中,mypyPyCharm s'类型检查器是执行验证的那些,不是Python本身。 Python目前不使用此信息,它仅将其存储为元数据并在执行期间忽略它。

答案 2 :(得分:8)

Python中的类型注释并不意味着类型强制。涉及运行时静态类型依赖的任何事情都意味着变化如此根本,以至于继续调用生成的语言甚至没有意义#34; Python"。

请注意,Python的动态特性允许使用pure-python代码构建外部工具来执行运行时类型检查。它会使程序运行(非常)缓慢,但它可能适用于某些测试类别。

可以肯定的是 - Python语言的基础之一是所有东西都是对象,并且您可以尝试在运行时对对象执行任何操作。如果对象没有符合尝试操作的接口,它将在运行时失败。

本质上静态输入的语言以不同的方式工作:在运行时尝试对象时,操作只需要对象。在编译步骤中,编译器为整个地方的相应对象创建空格和槽 - 而且,在不符合的类型中,会中断编译。

Python的类型检查允许任意数量的工具完全执行:在实际运行应用程序之前的一个步骤中打破并发出警告(但独立于编译本身)。但是语言的本质不能改变为实际上要求对象在运行时遵守 - 并且在编译步骤中打字和打破本身是非常人为的。

虽然可以预期Python的未来版本可能会对Python运行时本身进行编译时类型检查 - 最有可能通过和可选的命令行切换。 (我不认为它会违约 - 至少不会破坏构建 - 也许它可以默认发出警告)

因此,Python不需要在运行时进行静态类型检查,因为它将不再是Python。但至少有一种语言可以同时使用动态对象和静态类型 - Cython语言,它实际上可以作为Python超集。人们应该期望Cython能够很快将新的类型提示语法合并为实际的类型声明。 (目前它对可选的静态类型变量使用不同的语法)