如何在 python 3.6 中使用类型提示?
How to use type hints in python 3.6?
我注意到 Python 3.5 和 Python 3.6 添加了很多关于静态类型检查的功能,所以我尝试使用以下代码(在 python 3.6,稳定版本中)。
from typing import List
a: List[str] = []
a.append('a')
a.append(1)
print(a)
令我惊讶的是,Python 没有给我错误或警告,尽管 1
附加到 list
应该只包含字符串。 Pycharm
检测到类型错误并给了我一个警告,但它并不明显并且没有显示在输出控制台中,我担心有时我可能会错过它。我想要以下效果:
- 如果很明显我使用了错误的类型,如上所示,抛出警告或错误。
- 如果编译器不能可靠地检查我使用的类型是对还是错,请忽略它。
这可能吗?也许 mypy
可以做到,但我更愿意使用 Python-3.6 风格的类型检查(如 a: List[str]
)而不是注释风格(如 # type List[str]
)用于 mypy
。而且很好奇native python 3.6有没有switch来实现我上面说的两点
类型提示完全被 Python 运行时忽略,并且仅由 mypy 和 Pycharm 的集成检查器等第 3 方工具检查。还有各种鲜为人知的第 3 方工具使用类型注释在编译时或运行时进行类型检查,但大多数人使用 mypy 或 Pycharm 的集成检查器 AFAIK。
事实上,我怀疑在可预见的将来类型检查是否会集成到 Python 中——请参阅 PEP 484 (which introduced type annotations) and PEP 526 (which introduced variable annotations), as well as Guido's comments here 的 'non-goals' 部分。
我个人很乐意将类型检查与 Python 更紧密地集成在一起,但似乎整个 Python 社区都没有准备好或愿意进行这样的更改。
最新版本的 mypy 应该能理解 Python 3.6 变量注释语法和注释式语法。事实上,变量注释基本上是 Guido 的想法(Guido 目前是 mypy 团队的一员)——基本上,mypy 和 Python 中对类型注释的支持几乎是同时开发的。
Is that possible? Maybe mypy could do it, but I'd prefer to use Python-3.6-style type checking (like a: List[str]
) instead of the comment-style (like # type: List[str]
) used in mypy. And I'm curious if there's a switch in native python 3.6 to achieve the two points I said above.
Python 不可能为您做这件事;您 可以 使用 mypy
进行类型检查(PyCharms 内置检查器也应该这样做)。除此之外,mypy
也不限制你只能输入注释# type List[str]
,你可以像在Python中那样使用变量注释3.6 所以 a: List[str]
同样有效。
按原样使用 mypy
,因为该版本是最新的,您需要安装 typed_ast
并使用 --fast-parser
和 --python-version 3.6
执行 mypy
as documented in mypy's docs。这可能很快就会改变,但现在你需要他们运行顺利
更新: 现在不需要 --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、mypy
和 PyCharm
类型提示的类型提示的答案中提到的那样执行验证,而不是 Python 本身。 Python 目前不使用此信息,它仅将其存储为元数据并在执行期间忽略它。
Python 中的类型注释并不意味着类型强制。任何涉及 运行time 静态类型依赖的事情都将意味着根本性的变化,以至于继续调用生成的语言 "Python".
甚至没有意义
请注意 Python 的动态特性确实允许使用纯 python 代码构建外部工具来执行 运行time 类型检查。它会使程序 运行(非常)缓慢,但也许它适合某些测试类别。
可以肯定的是 - Python 语言的基本原理之一是一切都是对象,并且您可以尝试在 运行 时间对对象执行任何操作。如果对象没有符合尝试操作的接口,它将在 运行 时间失败。
本质上是静态类型的语言以不同的方式工作:在 运行 时间尝试时,操作只需要在对象上可用。在编译步骤中,编译器在各处为适当的对象创建空间和槽 - 并且,在不符合要求的类型上,中断编译。
Python 的类型检查允许任意数量的工具准确地做到这一点:在实际 运行 应用程序之前的某个步骤中断并发出警告(但独立于编译本身)。但是语言的性质无法更改为实际上要求对象在 运行 时间内遵守 - 而且在编译步骤本身进行打字和中断本身就是人为的。
虽然,可以预期 Python 的未来版本可能会在 Python 运行 时间本身上合并编译时类型检查 - 最有可能通过和可选的命令行开关。 (我认为它永远不会是默认的——至少不会破坏构建——也许它可以成为发出警告的默认值)
因此,Python 不需要在 运行 时进行静态类型检查,因为它将不再是 Python。但是至少存在一种同时使用动态对象和静态类型的语言——Cython 语言,它在实践中作为 Python 超集工作。人们应该期待 Cython 很快将新的类型提示语法合并为实际的类型声明。 (目前它对可选的静态类型变量使用不同的语法)
我注意到 Python 3.5 和 Python 3.6 添加了很多关于静态类型检查的功能,所以我尝试使用以下代码(在 python 3.6,稳定版本中)。
from typing import List
a: List[str] = []
a.append('a')
a.append(1)
print(a)
令我惊讶的是,Python 没有给我错误或警告,尽管 1
附加到 list
应该只包含字符串。 Pycharm
检测到类型错误并给了我一个警告,但它并不明显并且没有显示在输出控制台中,我担心有时我可能会错过它。我想要以下效果:
- 如果很明显我使用了错误的类型,如上所示,抛出警告或错误。
- 如果编译器不能可靠地检查我使用的类型是对还是错,请忽略它。
这可能吗?也许 mypy
可以做到,但我更愿意使用 Python-3.6 风格的类型检查(如 a: List[str]
)而不是注释风格(如 # type List[str]
)用于 mypy
。而且很好奇native python 3.6有没有switch来实现我上面说的两点
类型提示完全被 Python 运行时忽略,并且仅由 mypy 和 Pycharm 的集成检查器等第 3 方工具检查。还有各种鲜为人知的第 3 方工具使用类型注释在编译时或运行时进行类型检查,但大多数人使用 mypy 或 Pycharm 的集成检查器 AFAIK。
事实上,我怀疑在可预见的将来类型检查是否会集成到 Python 中——请参阅 PEP 484 (which introduced type annotations) and PEP 526 (which introduced variable annotations), as well as Guido's comments here 的 'non-goals' 部分。
我个人很乐意将类型检查与 Python 更紧密地集成在一起,但似乎整个 Python 社区都没有准备好或愿意进行这样的更改。
最新版本的 mypy 应该能理解 Python 3.6 变量注释语法和注释式语法。事实上,变量注释基本上是 Guido 的想法(Guido 目前是 mypy 团队的一员)——基本上,mypy 和 Python 中对类型注释的支持几乎是同时开发的。
Is that possible? Maybe mypy could do it, but I'd prefer to use Python-3.6-style type checking (like
a: List[str]
) instead of the comment-style (like# type: List[str]
) used in mypy. And I'm curious if there's a switch in native python 3.6 to achieve the two points I said above.
Python 不可能为您做这件事;您 可以 使用 mypy
进行类型检查(PyCharms 内置检查器也应该这样做)。除此之外,mypy
也不限制你只能输入注释# type List[str]
,你可以像在Python中那样使用变量注释3.6 所以 a: List[str]
同样有效。
按原样使用 mypy
,因为该版本是最新的,您需要安装 typed_ast
并使用 --fast-parser
和 --python-version 3.6
执行 mypy
as documented in mypy's docs。这可能很快就会改变,但现在你需要他们运行顺利
更新: 现在不需要 --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、mypy
和 PyCharm
类型提示的类型提示的答案中提到的那样执行验证,而不是 Python 本身。 Python 目前不使用此信息,它仅将其存储为元数据并在执行期间忽略它。
Python 中的类型注释并不意味着类型强制。任何涉及 运行time 静态类型依赖的事情都将意味着根本性的变化,以至于继续调用生成的语言 "Python".
甚至没有意义请注意 Python 的动态特性确实允许使用纯 python 代码构建外部工具来执行 运行time 类型检查。它会使程序 运行(非常)缓慢,但也许它适合某些测试类别。
可以肯定的是 - Python 语言的基本原理之一是一切都是对象,并且您可以尝试在 运行 时间对对象执行任何操作。如果对象没有符合尝试操作的接口,它将在 运行 时间失败。
本质上是静态类型的语言以不同的方式工作:在 运行 时间尝试时,操作只需要在对象上可用。在编译步骤中,编译器在各处为适当的对象创建空间和槽 - 并且,在不符合要求的类型上,中断编译。
Python 的类型检查允许任意数量的工具准确地做到这一点:在实际 运行 应用程序之前的某个步骤中断并发出警告(但独立于编译本身)。但是语言的性质无法更改为实际上要求对象在 运行 时间内遵守 - 而且在编译步骤本身进行打字和中断本身就是人为的。
虽然,可以预期 Python 的未来版本可能会在 Python 运行 时间本身上合并编译时类型检查 - 最有可能通过和可选的命令行开关。 (我认为它永远不会是默认的——至少不会破坏构建——也许它可以成为发出警告的默认值)
因此,Python 不需要在 运行 时进行静态类型检查,因为它将不再是 Python。但是至少存在一种同时使用动态对象和静态类型的语言——Cython 语言,它在实践中作为 Python 超集工作。人们应该期待 Cython 很快将新的类型提示语法合并为实际的类型声明。 (目前它对可选的静态类型变量使用不同的语法)