Python中给函数添加注解

转自Python3新特性:类型注解

这几天在看别人的算法源码时,发现有这样的代码

1
2
3
4
5
6
7
8
if sys.version_info >= (3, 6):
def __init__(self, days: float = ..., seconds: float = ..., microseconds: float = ...,
milliseconds: float = ..., minutes: float = ..., hours: float = ...,
weeks: float = ..., *, fold: int = ...) -> None: ...
else:
def __init__(self, days: float = ..., seconds: float = ..., microseconds: float = ...,
milliseconds: float = ..., minutes: float = ..., hours: float = ...,
weeks: float = ...) -> None: ...

一开始不知道参数后面的float=…是什么意思,后来查找资料才知道这是函数注解

我们都知道Python是一种动态语言,变量以及函数的参数是不区分类型的,这样的好处是有极大的灵活性,但坏处就是对于别人的代码,无法一眼判断出参数的类型,IDE也无法给出正确的提示

于是Python3中引入了新的特性:函数注解

就是类似这样的代码

1
2
def add(x: int, y: int) -> int:
return x + y

用 : 指定参数类型,用 -> 指定函数返回值的类型

不过特别要强调的是,Python 解释器并不会因为这些注解而提供额外的校验,没有任何的类型检查工作,也就是说,这些类型注解加不加,对你的代码来说没有任何影响

1
2
3
4
5
6
def add(x: int, y: int) -> int:
return x + y

print(add(2, 3))
print(add(3.5, 4.3))
print(add("py", "thon"))

输出是

1
2
3
5
7.8
python

但这么做的好处是:

  1. 让别的程序员看得更明白

  2. 让 IDE 了解类型,从而提供更准确的代码提示、补全和语法检查(包括类型检查,可以看到 str 和 float 类型的参数被高亮提示)

在函数的 __annotations__ 会有自己设定的注解

1
2
3
4
def add(x: int, y: int) -> int:
return x + y

print(add.__annotations__)

输出为

1
{'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}

在Python 3.6中,又引入了对变量类型进行注解的方法:

1
2
a: int = 123
b: str = "python"

更进一步,如果你需要指明一个全部由整数组成的列表:

1
2
from typing import List
l: List[int] = [1, 2, 3]

但同样,这些仅仅是注解,不会对代码产生任何影响

不过,你可以通过 mypy 库来检验最终代码是否符合注解

安装mypy

1
pip install mypy

执行代码:

1
mypy test.py

如果类型都符合,则不会有任何输出,否则就会给出类似输出: