Python学习笔记——11.类型注解
虽然 Python
作为动态语言具有极高的灵活性,编程非常便利,但是为了让程序更加清晰可读,有必要加入类型注解,要求
Python 3.9+,一些关于类型注解需要的内容在 typing
模块,下面有的语句在高版本中可以省略导入typing
模块。
类型注解不是强制的,并不会真正影响Python脚本的执行,但是静态代码检查可以基于类型注解提供警告,以提高编程的可靠性。这种类型检查的使用也很繁琐,容易误报警告,过度使用类型注解会丧失Python的灵活性。
变量注解
在定义变量时可以注解它的类型,这对静态代码分析很有帮助,例如
1 | age: int = 20 |
第二行会标红:静态检查不通过,但是代码仍然可以正常执行。
注意:
- 在 VScode+jupyter 中,只有处于同一个 cell 的代码才会执行静态检查,不同 cell 之间不会进行检查。
- 这种变量类型注解写错了可能找不出来,例如
age: float = 20
,这不会影响程序执行效果,但是会误导静态分析。
例如几种基本的类型
1 | a: int = 3 |
对于列表,字典,元组等复合类型,直接使用 list
或
dict
不能体现其中元素的类型,可以使用下面的形式(注意是中括号,并且要求
Python 版本很高)
1 | a: list[int] = [1, 2, 3] |
注意 list
支持不同的类型元素,可以使用如下语法
1 | from typing import Union |
或者对于 Python 3.10+,可以直接使用
1 | a: list[int|str] = [1, 'a', 2] |
1 | def mix(scores: list[int], ages: dict[str, int]) -> tuple[int, int]: |
函数注解
对函数的注解包括两部分:参数注解和函数返回值注解,对函数的注解是最常用的需求。
几个简单的例子如下 1
2
3
4
5
6
7
8def do_nothing() -> None:
pass
def say_hi(name: str) -> str:
return f'Hello {name}!'
def add(first: int = 10, second: float = 5.5) -> float:
return first + second
关于函数返回值的注解,考虑几个特殊情形:
可选返回值,返回某个类型或者 None,例如
1
2
3
4
5
6
7from typing import Optional
def foo(a: int = 0) -> Optional[str]:
if a == 1:
return 'Yeah'
else:
return None # 或者省略,隐式返回None多个返回值,可能返回某几个类型之一,例如
1
2
3
4
5
6
7
8
9from typing import Union
def foo(a: int = 0) -> Union[str, int, float]:
if a == 1:
return 'h'
elif a == 2:
return 1
else:
return 1.0无返回值,注意默认情形下 Python 的函数返回 None,无返回值只用于必然引起异常的情形,例如
1
2
3
4from typing import NoReturn
def hello() -> NoReturn:
raise RuntimeError('oh no')
可调用对象注解
对于可调用对象(函数,自定义类等)自身,可以使用
Callable
类型注解
1 | from typing import Callable |
可以指定可调用对象的细节,包括参数类型和返回值类型,例如
1 | from typing import Callable |
可以如下使用
1 | def t1() -> str: |
补充
自定义类型注解
在类型注解时可以使用自定义的类型,例如 1
2
3
4
5
6
7class Person:
def __init__(self, name: str):
self.name = name
def hello(p: Person) -> str:
return f'Hello, {p.name}'
有时类的定义尚未实现,或者为了避免循环依赖,可以使用同名的字符串代替
1
2
3
4
5
6
7def hello(p: 'Person') -> str:
return f'Hello, {p.name}'
class Person:
def __init__(self, name: str):
self.name = name
万能注解Any
万能的 Any
类型注解,用在不知道写什么注解的时候,例如
1 | from typing import Any |