Python类型标准(Type Hints)详解

Python 的类型标注(Type Hints) 是 Python 3.5+ 引入的语法,核心作用是给变量、函数参数 / 返回值标注 "预期类型" ------ 它不影响代码运行(Python 仍是动态类型语言),但能让开发者、编辑器(如 VS Code/PyCharm)和静态检查工具(如 mypy)明确代码的类型逻辑,大幅提升可读性和可维护性。

一、为什么要用?

  • 代码自文档化:一眼看懂变量 / 函数的类型意图(比如 age: int 明确是整数,不用看注释);
  • 编辑器智能提示:补全属性、提示类型错误(比如给 int 类型变量调用 split() 会直接标红);
  • 提前发现 bug:静态检查工具(mypy)能在运行前找出类型不匹配的问题(比如传字符串给需要整数的参数);
  • 团队协作友好:避免因 "猜类型" 导致的错误,尤其适合大型项目/自定义库开发。

二、变量标注

1、基本写法

用 "变量名:类型 = 值" 的格式,: 是类型标注的分隔符,右边是预期类型。

python 复制代码
# 基础类型标注
age: int = 25                # 整数
name: str = "张三"           # 字符串
is_valid: bool = True        # 布尔值
score: float = 98.5          # 浮点数

# 容器类型(Python 3.9+ 推荐小写,3.8- 需从 typing 导入大写)
nums: list[int] = [1, 2, 3]  # 整数列表
person: dict[str, str] = {"name": "张三", "city": "北京"}  # 字符串键值对字典
coords: tuple[int, float] = (10, 20.5)  # 固定长度的元组(第1个int,第2个float)

2、可选类型(允许为 None)

用 "Optional[类型]"(3.8-)或 "类型 | None"(3.10+)标注 "变量可以是指定类型,也可以是 None":

python 复制代码
# Python 3.8- 需导入 Optional
from typing import Optional
connection: Optional[str] = None  # 可以是字符串,也可以是 None

# Python 3.10+ 更简洁(无需导入)
connection: str | None = None

3、前向引用(标注未定义的类)

如果标注的类型是尚未定义的类,用字符串包裹类名(或导入 from future import annotations):

python 复制代码
# 写法1:字符串前向引用(兼容所有版本)
all_contacts: list["Contact"] = []

# 写法2:导入 annotations(3.7+),无需引号
from __future__ import annotations
all_contacts: list[Contact] = []

# 后续定义 Contact 类
class Contact:
    name: str
    phone: str

三、函数标注

1、基本写法

用 "def 函数名(参数名: 类型, ...) -> 返回值类型:" 的格式,"->" 标注返回值类型。

python 复制代码
# 基础函数标注
def add(a: int, b: int) -> int:
    return a + b

# 带默认值的参数标注(类型写在参数名后,默认值前)
def greet(name: str = "陌生人") -> str:
    return f"你好,{name}!"

# 可选参数(允许为 None)
from typing import Optional
def get_user(id: int) -> Optional[dict]:  # 返回字典或 None
    if id <= 0:
        return None
    return {"id": id, "name": "张三"}

2、不定参数标注

python 复制代码
# 可变长度参数 *args(元组)和 **kwargs(字典)
def print_nums(*args: int) -> None:  # *args 是整数元组,无返回值
    for num in args:
        print(num)

def print_info(**kwargs: str) -> None:  # **kwargs 是字符串值的字典
    for k, v in kwargs.items():
        print(f"{k}: {v}")

print_nums(1, 2, 3)  # 合法
print_info(name="张三", age="25")  # 合法(age 传字符串也不会运行报错,但静态检查会提示)

3. 任意类型(兜底标注)

如果不确定类型,用 Any(需导入)标注 "任意类型都允许":

python 复制代码
from typing import Any

def process_data(data: Any) -> Any:
    # 处理任意类型的数据
    return data

四、自定义类型 / 复杂类型

1、自定义类作为类型

标注自定义类的实例,直接用类名:

python 复制代码
class Waveguide:
    nc: float  # 类内变量标注
    t: float

    def __init__(self, nc: float, t: float) -> None:
        self.nc = nc
        self.t = t

# 标注 Waveguide 实例
wg: Waveguide = Waveguide(1.5, 2e-6)

# 标注存储 Waveguide 实例的列表
wg_list: list[Waveguide] = [wg, Waveguide(1.45, 3e-6)]

2、联合类型(多种类型可选)

用 Union[类型1, 类型2](3.8-)或 类型1 | 类型2(3.10+)标注 "可以是多种类型之一":

python 复制代码
# Python 3.8- 需导入 Union
from typing import Union
score: Union[int, float] = 98  # 可以是整数或浮点数

# Python 3.10+ 更简洁
score: int | float = 98.5

3. 类型别名(简化复杂类型)

给复杂类型起别名,提升可读性:

python 复制代码
# 定义类型别名
from typing import List, Dict
ScoreDict = Dict[str, List[int]]  # 字符串键,整数列表值的字典

# 使用别名
def get_class_scores() -> ScoreDict:
    return {"一班": [90, 85, 95], "二班": [88, 92, 89]}
相关推荐
captain3763 分钟前
JDBC(Java Data Base Connectivity)
java·开发语言
南境十里·墨染春水10 分钟前
C++笔记 STL——vector
开发语言·c++·笔记
zhangchaoxies14 分钟前
c++怎么在Linux下获取文件被最后一次访问的精确纳秒时间【进阶】
jvm·数据库·python
拾-光15 分钟前
LTX-Video 2.3 实战:用图片生成视频,消费级显卡也能跑的开源 I2V 模型(GPT Image 2)
java·人工智能·python·深度学习·算法·机器学习·音视频
m0_7478545216 分钟前
c++怎么在Linux下获取文件被最后一次访问的精确纳秒时间【进阶】
jvm·数据库·python
懷淰メ16 分钟前
【AI加持】基于PyQt+YOLO+DeepSeek的安全帽检测系统(详细介绍)
yolo·目标检测·计算机视觉·pyqt·安全帽检测·deepseek·安全帽
AVA洋16 分钟前
初识Coze(扣子)工作流,ai视频自动化制作
人工智能·python·大模型
2301_8166602117 分钟前
如何用HTML函数工具检测当前设备性能_内置诊断操作【操作】
jvm·数据库·python
zhangchaoxies28 分钟前
CSS如何实现移动端视口适配_利用rem与vw单位构建响应式布局
jvm·数据库·python
曲幽33 分钟前
FastAPI 文件上传避坑全指南:分块存盘、类型校验与安全兜底
python·upload·fastapi·web·file·chunk·validate·filetype