Python中的类型声明typing

前言

typing是 Python 的一个标准库模块,它在 Python 3.5 及以上版本中引入。

主要用于提供类型提示(type hints),让代码的可读性更强,并且可以帮助开发工具(如 IDE)提供更好的代码自动补全、类型检查等功能。

但需要注意的是,Python 仍然是一门动态类型语言,这些类型提示并不会在运行时强制类型约束。

变量的声明

1
2
3
from typing import int

x: int = 5

普通参数的声明

1
2
def add_numbers(a: int, b: int):
return a + b

方法参数声明

固定参数

1
2
3
4
5
6
7
8
9
10
from typing import Callable

def outer_func(callback: Callable[[int, int], int]):
result = callback(3, 5)
print(result)

def add_numbers(a: int, b: int) -> int:
return a + b

outer_func(add_numbers)

可变数量参数

1
2
3
4
5
6
7
8
9
10
from typing import Callable, Any

def outer_func_2(callback: Callable[..., Any]):
result = callback(1, 2, key='value')
print(result)

def variadic_function(*args, **kwargs):
return sum(args)

outer_func_2(variadic_function)

这里Callable[..., Any]中的...表示接受任意数量和类型的参数,Any表示返回值可以是任意类型(根据实际传入的函数来定)。

可空函数

1
2
3
4
5
6
7
8
9
10
from typing import Optional, Literal, Tuple, Callable

def acquire(
on_scan_img: Optional[Callable[[str], None]] = None,
on_scan_finish: Optional[Callable[[], None]] = None,
on_scan_error: Optional[Callable[[Exception], None]] = None,
) -> None:
# 调用后处理函数
if on_scan_img is not None:
on_scan_img(img_path)

返回值声明

如果函数可能返回None,可以使用Optional类型。

1
2
3
4
5
6
from typing import Optional

def divide_numbers(a: int, b: int) -> Optional[float]:
if b == 0:
return None
return a / b

各种类型示例

列表

1
2
3
4
5
from typing import List

def print_strings(str_list: List[str]):
for s in str_list:
print(s)

字典

1
2
3
4
5
from typing import Dict

def print_dict_values(int_dict: Dict[str, int]):
for key, value in int_dict.items():
print(key, value)

泛型

1
2
3
4
5
6
from typing import TypeVar, List

T = TypeVar('T')

def first_element(lst: List[T]) -> T:
return lst[0]

自定义类型

1
2
3
4
5
6
7
from typing import NewType

UserId = NewType('UserId', int)

def get_user_name(user_id: UserId):
# 假设这里有获取用户名字的逻辑
pass

字面量

Literal类型是从 Python 3.8 版本开始引入的。

它的出现使得在类型提示中能够更精确地指定变量或者函数参数只能取特定的几个字面量值,增强了类型系统对于代码中固定取值情况的表达能力。

在旧版本的 Python 中如果想要实现类似的限制功能,可以需要通过自定义验证函数或者枚举(Enum)等来实现类似的效果。

1
2
3
4
from typing import Literal

def print_specific_string(s: Literal["gray", "color"]):
print(s)

综合示例

1
2
3
4
5
6
7
8
9
10
from typing import Dict, List, Literal, Optional, Tuple
def acquire(
save_folder: str,
dsm_name: Optional[str] = None,
dpi: Optional[float] = None,
show_ui: bool = False,
pixel_type: Optional[Literal["bw", "gray", "color"]] = "color",
frame: Optional[Tuple[float, float, float, float]] = None,
) -> Optional[List[Dict]]:
pass