Python 在版本3.6 中添加了一些称为变量注释的语法。变量注释基本上是一种增强的类型暗示, 这是在 Python 3.5 中引入的。在PEP 526中解释了变量注释背后的完整解释。在本文中, 我们给出了对类型提示的快速复习, 然后介绍了新的变量注释语法。
什么是类型提示?
Python 中的类型提示基本上声明函数和方法中的参数具有某种类型。Python 不强制执行类型 “提示”, 但您可以使用像mypy这样的工具来强制执行类型提示, 这与 c++ 在运行时强制类型声明的方式非常类似。让我们看一个没有添加类型提示的正常函数:
def add(a, b):
return a + b
if __name__ == '__main__':
add(2, 4)
这里我们创建一个 add()
函数, 它需要两个参数。它添加两个参数并返回结果。我们不知道的是我们需要传递给函数。我们可以将整数、浮点、列表或字符串传递给它, 这很可能会起作用。但它会以我们预期的方式运作吗?让我们在代码中添加一些类型提示:
def add(a: int, b: int) -> int:
return a + b
if __name__ == '__main__':
print(add(2, 4))
在这里, 我们更改函数的定义以使用类型提示。您会注意到, 现在参数被标记为它们应该是什么类型:
-
a:int
-
b:int
我们还提示返回值, 即 ” -> int
” 是什么。这意味着我们期望一个整数作为我们的返回值。add()
但是, 如果尝试使用几个字符串或浮点和整数调用函数, 则不会看到错误。正如我所说, Python 只是允许您提示参数的类型应该是什么, 但它不强制执行它。
让我们将代码更新到以下内容:
def add(a: int, b: int) -> int:
return a + b
if __name__ == '__main__':
print(add(5.0, 4))
如果您运行此, 您将看到它执行只是罚款。现在让我们使用 pip 安装 mypy:
pip install mypy
现在我们已经有了 mypy, 我们可以用它来确定我们是否正确使用了我们的功能。打开终端并导航到保存上述脚本的文件夹。然后执行以下命令:
mypy hints.py
当我运行此命令时, 我收到以下输出:
hints.py:5: error: Argument 1 to "add" has incompatible type "float"; expected "int"
正如您所看到的, mypy 发现我们的代码有问题。我们正在为第一个参数而不是 int 传递一个浮点型。您可以在连续集成服务器上使用 mypy, 在提交到分支之前, 或在提交代码之前在本地运行之前, 可以检查代码是否存在这些类型的问题。
变量注释
假设您希望不仅注释函数参数, 还要标注常规变量。在 Python 3.5 中, 您无法使用与函数参数相同的语法, 因为它会引发语法错误。相反, 你需要使用注释, 但现在3.6 已经出来了, 我们可以使用新的语法!让我们看一个例子:
from typing import List
def odd_numbers(numbers: List) -> List:
odd: List[int] = []
for number in numbers:
if number % 2:
odd
如果您对此脚本运行 mypy, 您将不会收到任何输出, 因为我们正在正确地执行所有操作。让我们尝试更改代码以添加除整数以外的其他内容!
from typing import List
def odd_numbers(numbers: List) -> List:
odd: List[int] = []
for number in numbers:
if number % 2:
odd.append(number)
odd.append('foo')
return odd
if __name__ == '__main__':
numbers = list(range(10))
print(odd_numbers(numbers))
在这里, 我们添加一个新行, 将字符串追加到整数列表中。现在, 如果我们对此版本的代码运行 mypy, 我们应该看到以下内容:
hints2.py:9: error: Argument 1 to "append" of "list" has incompatible type "str"; expected "int"
只是要重申, 在 Python 3.5 中, 您可以执行变量注释, 但必须将注释放在注释中:
# Python 3.6
odd: List[int] = []
# Python 3.5
odd = [] # type: List[int]
请注意, 如果更改代码以使用 Python 3.5 变量注释语法的变体, mypy 仍将正确标记错误。您必须指定 “类型:” 后的英镑符号虽然。如果删除该项, 则它不再是可变批注。基本上, 所有的PEP 526添加的是使语法更统一的整个语言。
包装
此时, 您应该有足够的信息开始在您自己的代码中执行变量注释, 无论您使用的是 Python 3.5 还是 3.6, 我认为这是一个很好的概念, 对于那些与其他更熟悉的人一起工作的程序员特别有用。静态的、类型化的语言。