Typing 泛型--容器类型
Typing 泛型--容器类型
概述
容器类型指的是 数据结构 中的 列表, 字典,集合,元组等的数据类型,Python 的容器类型,可以存储的数据类型是任意的,不像其他静态类型语言一样,是需要声明容器类型里存储的数据类型。
Typing 模块中容器类型的类型标注,也是一种泛型类型标注,可以对数据结构中的值进行类型标注,可以细致到对应数据结构中的元素类型,程序在执行中依然是不进行强制校验的,但是 Typing 的容器类型标注,是常用也是最应该使用的类型标注方式
提示
在 Python 3.9+ 以后, python 原生的容器数据结构 list,dict,set,tuple 可以等同于 typing 中的 List,Dict,Set,Tuple 等类型,可以进行泛型约束,无需再导入 typing 模块但是在此之前的 python 版本中,原生的容器类型只能做简单的类型标注,表示该值为一个容器类型。
List
表示特定类型元素的列表
from typing import List
A : List[int] = [1, 2, 3]
B : List[str] = ["apple", "banana", "cherry"]
C : List[bool] = [True, False, True]
def sum_numbers(numbers: List[float]) -> float:
return sum(numbers)
total = sum_numbers([1.5, 2.5, 3.0]) # 7.0
Dict
表示特定类型元素的字典
from typing import Dict
A : Dict[str, int] = {"apple": 1, "banana": 2, "cherry": 3}
B : Dict[str, str] = {"name": "Alice", "age": "18", "city": "New York"}
C : Dict[str, bool] = {"is_student": True, "is_teacher": False, "is_professor": True}
D : Dict[str, list] = {"fruits": ["apple", "banana", "cherry"], "cities": ["New York", "London", "Paris"]}
def get_value(dictionary: Dict[str, str], key: str) -> str:
return dictionary[key]
value = get_value(B, "name")
print(value)
Set
表示特定类型元素的集合
from typing import Set
A : Set[int] = {1, 2, 3, 4, 5}
B : Set[str] = {"apple", "banana", "cherry"}
C : Set[bool] = {True, False, True}
D : Set[float] = {1.1, 2.2, 3.3, 4.4, 5.5}
def get_value(set_: Set[str], key: str) -> str:
return set_[key]
value = get_value(B, "apple")
FrozenSet
表示特定类型元素的只读集合
from typing import FrozenSet
A : FrozenSet[int] = frozenset([1, 2, 3, 4, 5])
B : FrozenSet[str] = frozenset(["apple", "banana", "cherry"])
C : FrozenSet[bool] = frozenset([True, False, True])
def get_value(set_: FrozenSet[str], key: str) -> str:
return set_[key]
value = get_value(B, "apple")
Tuple
表示特定类型元素的元组
from typing import Tuple
A: Tuple[int, int] = (1, 2)
B: Tuple[str, str, str] = ("apple", "banana", "cherry")
C: Tuple[bool] = (True,)
def get_value(tuple_: Tuple[str, str, str], index: int) -> str:
return tuple_[index]
value = get_value(B, 1)
value = get_value(C, 0) # 应为类型 'Tuple[str, str, str]',但实际为 'Tuple[bool]'
注意
Tuple 类型比如指定固定个数的元素标注,比如 Tuple[str, str, str],表示 tuple 中只能有 3 个元素,且第一个元素是 str,第二个元素是 str,第三个元素是 str。其他类型不需要
核心原因是 元组(Tuple)和其他容器(List, Set, Dict 等)在类型系统中的根本区别在于:元组是固定长度、固定类型的序列,而其他容器是可变长度、单一类型的集合。
Sequence
Sequence 是 python 中的序列类型,可以包含任意类型的元素,但不同于元组(Tuple),元组(Tuple)是固定长度、固定类型的序列
from typing import Sequence
A: Sequence[int] = [1, 2, 3, 4]
B: Sequence[str] = ["a", "b", "c", "d"]
def first_element(seq: Sequence[int]) -> int:
return seq[0] # 可以索引但不能修改
value = first_element([1, 2, 3]) # 1
value = first_element((4, 5, 6)) # 4
Mapping
Mapping 是 python 中的映射类型
Dict 是具体的字典类型,而 Mapping 是抽象的映射接口(协议),可以理解为键值对类型的抽象接口
from typing import Mapping
from collections import defaultdict, OrderedDict, UserDict
from types import MappingProxyType
# 接受任何映射对象(只读操作)
def read_mapping(data: Mapping[str, int]) -> None:
print(f"Keys: {list(data.keys())}")
print(f"Value for 'a': {data.get('a')}")
# data["new"] = 100 # 错误!Mapping是只读接口
# 所有这些都可以正常工作:
normal_dict = {"a": 1, "b": 2}
default_dict = defaultdict(int, {"a": 1, "b": 2})
ordered_dict = OrderedDict({"a": 1, "b": 2})
user_dict = UserDict({"a": 1, "b": 2})
readonly_dict = MappingProxyType({"a": 1, "b": 2}) # 不可变代理
read_mapping(normal_dict) # ✓
read_mapping(default_dict) # ✓
read_mapping(ordered_dict) # ✓
read_mapping(user_dict) # ✓
read_mapping(readonly_dict) # ✓