标题: Python 类型注解 [打印本页] 作者: 滴水恩情 时间: 2023-2-12 17:36 标题: Python 类型注解 在Python语言发展的过程中,PEP提案发挥了巨大的作用,如PEP 3107 和 PEP 484提案,分别给我们带来了函数注解(Function Annotations)和类型提示(Type Hints)的功能。
PEP 3107:定义了函数注解的语法,允许为函数的参数和返回值添加元数据注解。
PEP 484:按照PEP 3107函数注解的语法,从Python语法层面全面支持类型提示,类型提示可以是内置类型、内置类、抽象基类、types模块中提供的类型和开发人员自定义的类。
另外 PEP 526, PEP 544, PEP 586, PEP 589, PEP 591 这些东西对 PEP 3107 和 PEP 484 进行了补充,比如添加了变量注释,字面量注释这些东西。
需要注意的是,类型提示仅有提示的作用,这里的提示是指用户阅读Python代码的时候的提示,仅在语法层面支持,对代码的运行没有任何影响,Python 解释器在运行代码的时候会忽略类型提示,也就是说,Python的类型提示仅是为了提升代码可读性,一定程度上缓解"动态语言一时爽,代码重构火葬场"的尴尬。
下面将函数注解和类型提示,统称为类型注解。
是一种特殊的类型,每种类型都视为与Any兼容,同样,Any也与所有类型兼容。可以对Any类型的值执行任何操作或方法调用,并将其分配给任何变量。将Any类型的值分配给更精确的类型(more precise type)时,不会执行类型检查,所有没有返回类型或参数类型的函数都将隐式地默认使用Any。
使用Any,说明值是动态类型。
把所有的类型都注解为 Any 将毫无意义,因此 Any 应当尽量少使用
from typing import Any
def foo() -> Any:
pass
复制代码
抽象基类
# 在某些情况下,我们可能并不需要严格区分一个变量或参数到底是列表 list 类型还是元组 tuple 类型
# 可以使用一个更为泛化的类型,叫做 Sequence,其用法类似于 List
class typing.Sequence(Reversible[T_co], Collection[T_co])
# collections.abc.Iterator的泛型版本
# 注释函数参数中的迭代类型时,推荐使用的抽象集合类型
class typing.Iterable(Generic[T_co])
def print_iterable(x: Iterable):
for i in x:
print(i)
# collections.abc.Mapping的泛型(generic)版本
# 注释函数参数中的Key-Value类型时,推荐使用的抽象集合类型
class typing.Mapping(Sized, Collection[KT], Generic[VT_co])
复制代码
泛型:TypeVar
先抛出问题:
假设有一个函数,要求它既能够处理字符串,又能够处理数字。那么你可能很自然地想到了 Union ,如下:
from typing import Union
AddValue = Union[int, str]
def add(a: AddValue, b: AddValue) -> AddValue:
return a + b
if __name__ == "__main__":
print(add(1, 2)) # 类型检查通过,输出 3
print(add("1", "2")) # 类型检查通过,输出 12
print(add("1", 2)) # 类型检查通过,报错 TypeError: can only concatenate str (not "int") to str