Python 基础 - 类型注解 List、Dict、Tuple、Any
前面学习了 Type Hints 基础类型 int , str 以及简单的复合类型 list, tuple, dict。 接下来学习typing模块List, Dict, Tuple有什么不一样
typing 模块 List
以下例子中a和b都是声明了list类型。
- a的成员但是int类型
- b的成员但是str类型。
a: list = [1, 2, 3, 4, 5, 6, 7]
b: list = ["a", "b", "c", "d", "e", "f", "g"]
print(a)
print(b)
为了更精准声明list类型的成员是int 或 str,于是需要用到typing模块
from typing import List
a: List[int] = [1, 2, 3, 4, 5, 6, 7]
b: List[str] = ["a", "b", "c", "d", "e", "f", "g"]
print(a)
print(b)
list 和 List 的区别:
- list 只能声明类型,无法声明里面的成员是什么类型
- List 可以声明里面成员是什么类型
在函数中的例子
from typing import List
def demo_list(a: List[str], index: int) -> str:
res = a[index]
return res
r = demo_list(['aa', 'bb', 'cc'], 1)
print(r)
当我们需要从a列表中取值后,再调用相关方法,编辑器会自动识别到str对象的方法
如由数字或字符串构成的列表可以声明为:
def fun_a(a: List[int or str]) -> List:
return a
r = fun_a(['a', ['aa']])
还可以嵌套声明
x: List[List[int]]
Sequence 序列
可迭代对象(Iterable)是指能被for ..in 循环的对象。如我们常见的:list、str、tuple, dict、等是可迭代对象。 Sequence 是序列,内置的序列类型:list、str、tuple、bytes。注意dict不是,它是键值对的,没有下标值,只能根据可以去查找。 有时候,我们不在意传入的究竟是 list 还是tuple, 因为我们可能只是需要迭代这个对象而已。
from typing import Sequence
def demo_seq(s: Sequence, by: str) -> str:
return by.join(s)
r1 = demo_seq('hello', '_')
print(r1)
r2 = demo_seq(('a', 'b', 'c'), '_')
print(r2)
也可以指定Sequence 成员必须是字符串
Dict 类型
dict 是键值对格式,小写的dict 类型无法准确的声明键和值具体类型。 比如我想声明键是str, 值是int
from typing import Dict
def demo_dict(d: Dict[str, int]) -> Dict:
d.update({"aa": 22})
return d
r = demo_dict({"x": 1, "y": 2})
print(r)
Mapping 和 MutableMapping
Dict、字典,是 dict 的泛型;Mapping,映射,是 collections.abc.Mapping 的泛型。根据官方文档,Dict 推荐用于注解返回类型,Mapping 推荐用于注解参数。 它们的使用方法都是一样的,其后跟一个中括号,中括号内分别声明键名、键值的类型,如: ``
from typing import Mapping, Dict
def size(rect: Mapping[str, int]) -> Dict[str, int]:
return {'width': rect['width'] + 100, 'height': rect['width'] + 100}
这里将 Dict 用作了返回值类型注解,将 Mapping 用作了参数类型注解。MutableMapping 则是 Mapping 对象的子类,在很多库中也经常用 MutableMapping 来代替 Mapping。
Any 任意类型
如果值是任意类型,可以用Any
from typing import Dict, Any
def demo_dict(d: Dict[str, Any]) -> Dict:
d.update({"aa": 22})
return d
r = demo_dict({"x": 1, "y": "A", "z": ["a", "b"]})
print(r)
Tuple
空元组的类型可写成 Tuple[()]
def fun_a(a: Tuple[()]) -> Tuple:
return a
r = fun_a(())
元组里面只有一个成员
def fun_a(a: Tuple[str]) -> Tuple:
return a
r = fun_a(('aa', ))
print(r)
元组类型,Tuple[X, Y]
标注了一个二元组类型,其第一个元素的类型为 X 且第二个元素的类型为Y。
def fun_a(a: Tuple[str, int]) -> Tuple:
return a
r = fun_a(('aa', 12))
print(r)
Tuple[int, float, str]
表示一个由整数、浮点数和字符串组成的三元组
def fun_a(a: Tuple[int, float, str]) -> Tuple:
return a
r = fun_a((11, 12.1, "aa"))
print(r)
为表达一个同类型元素的变长元组,使用省略号字面量,如Tuple[int, ...]
。
def fun_a(a: Tuple[int, ...]) -> Tuple:
return a
r = fun_a((11, 12, 13, 14))
print(r)
单独的一个 Tuple 等价于 Tuple[Any, ...]
,进而等价于 tuple
Set、AbstractSet
Set、集合,是 set 的泛型;AbstractSet、是 collections.abc.Set 的泛型。根据官方文档,Set 推荐用于注解返回类型,AbstractSet 用于注解参数。它们的使用方法都是一样的,其后跟一个中括号,里面声明集合中元素的类型,如:
from typing import Set, AbstractSet
def describe(s: AbstractSet[int]) -> Set[int]:
return set(s)
这里将 Set 用作了返回值类型注解,将 AbstractSet 用作了参数类型注解。