用于标注函数的参数和返回值。
是一种在编译时将任意 Python 表达式与函数的多个部分联系起来的方式。
参数
identifier [: expression] [= expression]
比如:
def foo(a: str, b: int = 5):
:
用来标注 annotations。所有的 annotations 表达式只在函数定义被执行的时候执行。
附加的参数(比如 *args
和 **kwargs
)也是类似的:
def foo(*args: expression, **kwargs: expression):
比如:
def foo(**kwargs: Union[Dict[str, str], Dict[str, int]]):
返回值
在函数定义的 )
之后接上 ->
和一个 Python 表达式,比如:
def sum() -> expression:
def sum() -> int:
Lambda
Lambda 不支持 annotations。
获取函数的 annotations
编译完成后,函数的 annotations 可以通过函数的 func_annotations
获取。这个属性是一个可修改的字典,为函数参数名和 annotations 的匹配。有一个特殊的键 return
,用于对应返回值的 annotations。
[1] 中说是通过 func_annotations
能获取,但实际上 func 没有 func_annotations
这个属性。要通过 __annotations__
获取。
# -*- coding: utf-8 -*-
def foo(a: 'x', b: 5 + 6, c: list) -> max(2, 9):
pass
print(foo.__annotations__) # {'a': 'x', 'b': 11, 'c': <class 'list'>, 'return': 9}
使用 return
作为键的原因是,如果在函数参数中使用 return
会导致 SyntaxError
。
使用案例
- 类型检查[2]
- 让 IDE 展示一个函数的接收与返回
- 数据库查询匹配(类似 ORM?)
问题
- 是否可以指定 Dict 中的字段名?
- Dict 中的类型不一致如何标注,比如
{int: str, str: int}
- 如果强制实行标注,那么和静态类型有什么不一样?是否说明 Python 设计成动态类型是错误的?