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]}
相关推荐
無限進步D2 小时前
C++ 万能头
开发语言·c++·算法·蓝桥杯·竞赛·万能头
前端小趴菜~时倾2 小时前
自我提升-python爬虫学习:day01
爬虫·python·学习
小白学大数据2 小时前
小说爬虫实战:《斗罗大陆》章节自动抓取与合并
开发语言·爬虫·python·数据分析
qq_418101772 小时前
C++中的状态模式
开发语言·c++·算法
weixin_307779132 小时前
构建健壮的XML文档抓取与摘要流水线:Requests + urllib3.Retry + lxml 实践
xml·开发语言·python·算法·性能优化
如何原谅奋力过但无声2 小时前
【力扣-Python-74】搜索二维矩阵(middle)
数据结构·python·算法·leetcode·矩阵
怪侠_岭南一只猿2 小时前
爬虫工程师学习路径 · 阶段五:数据存储与清洗(完整学习文档)
爬虫·python·学习
weixin_649555672 小时前
C语言程序设计第四版(何钦铭、颜晖)第八章指针之判断回文字符串
c语言·开发语言·算法
XiYang-DING2 小时前
【Java SE】继承
java·开发语言