Logo
Published on

3.10.标准库模块

Authors
  • avatar
    Name
    xiaobai
    Twitter

1.概述

Python 标准库是 Python 安装时自带的模块集合,提供了丰富的功能来支持各种编程任务。掌握常用标准库模块是 Python 编程的重要技能。

2.核心模块分类

  • 系统相关ossyspathlib
  • 数据处理jsoncsvcollections
  • 时间处理datetimetime
  • 数学计算mathrandomstatistics
  • 文本处理restring
  • 函数式编程functoolsitertools
  • 类型注解typing

3.os - 操作系统接口

3.1.功能概述

os 模块提供操作系统相关功能,包括文件、目录、环境变量管理和系统命令执行。

3.2.主要功能

3.2.1.目录操作

import os

# 获取和切换工作目录
print("当前目录:", os.getcwd())
os.chdir('/tmp')  # 切换目录
print("切换后:", os.getcwd())

# 目录管理
os.makedirs('test_dir/sub_dir', exist_ok=True)  # 递归创建
os.rmdir('test_dir/sub_dir')  # 删除空目录
print("目录内容:", os.listdir('.'))

3.2.2.路径操作

file_path = '/home/user/document.txt'

# 路径分解
print("目录名:", os.path.dirname(file_path))
print("文件名:", os.path.basename(file_path))
print("路径分割:", os.path.split(file_path))
print("扩展名:", os.path.splitext(file_path))

3.2.3.环境变量

# 环境变量操作
print("PATH:", os.getenv('PATH'))
print("所有环境变量:", dict(os.environ))

3.2.4.系统命令

# 执行系统命令
result = os.system('ls -l')
print("命令结果:", result)

3.3.使用场景

  • 文件备份和批量处理
  • 环境配置管理
  • 跨平台路径处理
  • 系统命令执行

3.4.注意事项

  • 注意权限和异常处理
  • 避免误操作造成不可逆后果
  • 使用 pathlib 作为现代替代方案

4.sys - 系统相关功能

4.1.功能概述

sys 模块提供对 Python 解释器及其环境的访问,包括版本信息、命令行参数、模块路径等。

4.2.主要功能

4.2.1.解释器信息

import sys

# 获取解释器信息
print("Python版本:", sys.version)
print("平台信息:", sys.platform)
print("可执行文件路径:", sys.executable)

4.2.2.命令行参数

# 处理命令行参数
print("命令行参数:", sys.argv)

# 参数检查
if len(sys.argv) < 2:
    print("缺少参数")
    sys.exit(1)  # 错误退出

4.2.3.模块搜索路径

# 查看模块搜索路径
print("模块搜索路径:")
for path in sys.path:
    print(" ", path)

# 添加自定义路径
sys.path.append('/custom/module/path')

4.2.4.标准输入输出

# 标准输入输出流
sys.stdout.write("标准输出\n")
sys.stderr.write("错误输出\n")

4.2.5.内存管理

# 对象引用计数
x = [1, 2, 3]
print("引用计数:", sys.getrefcount(x))

4.3.使用场景

  • 命令行参数解析
  • 模块路径管理
  • 程序优雅退出
  • 输出流重定向
  • 调试和性能分析

4.4.注意事项

  • sys.exit()exit() 更安全
  • 谨慎修改 sys.path
  • 注意引用计数的准确性

5.datetime - 日期时间处理

5.1.功能概述

datetime 模块提供日期和时间处理功能,支持时间获取、格式化、运算和解析。

5.2.主要类型

  • datetime:包含日期和时间
  • date:仅包含日期
  • time:仅包含时间
  • timedelta:时间间隔

5.3.基本用法

5.3.1.获取当前时间

from datetime import datetime, date, time, timedelta

# 获取当前时间
now = datetime.now()
print("当前时间:", now)
print("格式化时间:", now.strftime("%Y-%m-%d %H:%M:%S"))

5.3.2.创建特定时间

# 创建特定时间
dt = datetime(2024, 1, 15, 14, 30, 0)
print("特定时间:", dt)

5.3.3.时间运算

# 时间加减
tomorrow = now + timedelta(days=1)
last_week = now - timedelta(weeks=1)
print("明天:", tomorrow)
print("上周:", last_week)

# 时间差计算
time_diff = tomorrow - now
print("时间差:", time_diff)
print("相差天数:", time_diff.days)
print("相差秒数:", time_diff.total_seconds())

5.3.4.时间组件

# 获取时间各部分
print("年:", now.year)
print("月:", now.month)
print("日:", now.day)
print("时:", now.hour)
print("分:", now.minute)
print("星期:", now.weekday())

5.3.5.字符串解析

# 字符串解析为时间对象
date_str = "2024-01-15 14:30:00"
parsed_date = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S")
print("解析后的时间:", parsed_date)

5.4.使用场景

  • 日志记录和时间戳
  • 数据分析和统计
  • 定时任务和调度
  • 用户界面时间显示

6.json - JSON数据处理

6.1.功能概述

json 模块用于处理 JSON 数据,支持 Python 对象与 JSON 字符串之间的转换。

6.2.基本用法

6.2.1.对象转JSON

import json

# Python对象转JSON字符串
data = {
    "name": "张三",
    "age": 25,
    "is_student": False,
    "hobbies": ["读书", "编程", "音乐"],
    "address": {
        "city": "北京",
        "street": "朝阳区"
    }
}

json_str = json.dumps(data, ensure_ascii=False, indent=2)
print("JSON字符串:")
print(json_str)

6.2.2.JSON转对象

# JSON字符串转Python对象
parsed_data = json.loads(json_str)
print("解析后的数据:", parsed_data)
print("姓名:", parsed_data["name"])

6.2.3.文件操作

# 写入JSON文件
with open('data.json', 'w', encoding='utf-8') as f:
    json.dump(data, f, ensure_ascii=False, indent=2)

# 读取JSON文件
with open('data.json', 'r', encoding='utf-8') as f:
    loaded_data = json.load(f)
    print("从文件加载的数据:", loaded_data)

6.2.4.自定义编码器

# 自定义对象编码
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

class PersonEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, Person):
            return {'name': obj.name, 'age': obj.age}
        return super().default(obj)

person = Person("李四", 30)
person_json = json.dumps(person, cls=PersonEncoder, ensure_ascii=False)
print("自定义对象JSON:", person_json)

6.3.支持的数据类型

Python类型JSON类型
dictobject
listarray
strstring
int/floatnumber
True/Falsetrue/false
Nonenull

6.4.使用场景

  • API数据交换
  • 配置文件存储
  • 数据持久化
  • 跨语言数据通信

7.collections - 高级数据结构

7.1.功能概述

collections 模块提供高性能、多用途的数据结构,扩展了内置类型的功能。

7.2.主要容器类型

7.2.1.Counter - 计数器

from collections import Counter

# 统计元素出现次数
words = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']
word_count = Counter(words)
print("词频统计:", word_count)
print("出现最多的2个:", word_count.most_common(2))

# 更新计数器
word_count.update(['apple', 'grape'])
print("更新后的计数器:", word_count)

7.2.2.defaultdict - 默认字典

from collections import defaultdict

# 默认值为列表的字典
dd = defaultdict(list)
dd['fruits'].append('apple')
dd['fruits'].append('banana')
dd['vegetables'].append('carrot')
print("默认字典:", dict(dd))

# 自定义默认值函数
def default_value():
    return "未知"

dd2 = defaultdict(default_value)
print("键不存在时的值:", dd2['nonexistent'])

7.2.3.OrderedDict - 有序字典

from collections import OrderedDict

# 有序字典(Python 3.7+ 内置dict已有序)
od = OrderedDict()
od['z'] = 1
od['a'] = 2
od['c'] = 3
print("有序字典:", list(od.keys()))

7.2.4.namedtuple - 命名元组

from collections import namedtuple

# 定义命名元组
Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)
print("点坐标:", p)
print("x坐标:", p.x)
print("y坐标:", p.y)

7.2.5.deque - 双端队列

from collections import deque

# 双端队列
dq = deque([1, 2, 3])
dq.append(4)      # 右端添加
dq.appendleft(0)  # 左端添加
print("双端队列:", dq)
print("右端弹出:", dq.pop())
print("左端弹出:", dq.popleft())

7.3.使用场景

  • Counter:词频统计、数据分析
  • defaultdict:聚合分组、桶分布
  • OrderedDict:保持插入顺序
  • namedtuple:增强可读性
  • deque:队列、栈、滑动窗口

8.re - 正则表达式

8.1.功能概述

re 模块提供正则表达式处理功能,支持字符串匹配、查找、替换、分割等操作。

8.2.常用函数

函数描述返回值
re.match()从字符串开头匹配匹配对象或None
re.search()搜索第一个匹配匹配对象或None
re.findall()查找所有匹配列表
re.finditer()返回匹配迭代器迭代器
re.sub()替换匹配内容新字符串
re.split()按匹配分割列表
re.compile()预编译正则正则对象

8.3.基本语法

符号描述示例
.任意字符a.c 匹配 "abc"
^字符串开头^start 匹配开头
$字符串结尾end$ 匹配结尾
*0次或多次ab* 匹配 "a", "ab", "abb"
+1次或多次ab+ 匹配 "ab", "abb"
?0次或1次ab? 匹配 "a", "ab"
{m,n}m到n次a{2,4} 匹配 "aa", "aaa", "aaaa"
[]字符集[a-z] 匹配小写字母
``
\d数字\d+ 匹配数字
\w字母数字下划线\w+ 匹配单词
\s空白字符\s+ 匹配空格
()分组(ab)+ 匹配 "ab", "abab"

8.4.使用示例

import re

text = "小王的邮箱是: kwang@mail.com, 电话: 188-1234-5678。还有一个邮箱:abc_xyz@company.org, 另外电话: 139-8765-4321。"

# 1. match:只检查是否从开头匹配
result = re.match(r'小王的邮箱是', text)
if result:
    print("match - 匹配到字符串开头:", result.group())

# 2. search:查找第一个邮箱
email = re.search(r'\w+@\w+\.\w+', text)
if email:
    print("search - 第一个邮箱:", email.group())

# 3. findall:查找所有电话号码
phones = re.findall(r'\d{3}-\d{4}-\d{4}', text)
print("findall - 所有电话:", phones)

# 4. finditer:遍历所有邮箱并打印位置信息
print("finditer - 所有邮箱位置和内容:")
for match in re.finditer(r'\w+@\w+\.\w+', text):
    print(f"邮箱: {match.group()},起始: {match.start()},结束: {match.end()}")

# 5. split:按中文全角逗号和冒号分割
fragments = re.split(r'[::,,]', text)
print("split - 分割结果:", fragments)

# 6. compile:预编译正则以提高多次匹配效率
pattern = re.compile(r'\w+@\w+\.\w+')
emails = pattern.findall(text)
print("compile - 所有邮箱:", emails)

# 7. 分组匹配
m = re.match(r'(\w+)的邮箱是: (\w+@\w+\.\w+)', text)
if m:
    print("match.group(0):", m.group(0))  # 整体
    print("match.group(1):", m.group(1))  # "小王"
    print("match.group(2):", m.group(2))  # 邮箱

# 8. sub:替换所有数字为*
anonymized = re.sub(r'\d', '*', text)
print("sub - 隐私处理后:", anonymized)

8.5.使用场景

  • 文本处理和清洗
  • 数据提取和验证
  • 格式检查和转换
  • 日志分析和解析

8.6.使用示例

import re

text = "小王的邮箱是: kwang@mail.com, 电话: 188-1234-5678。还有一个邮箱:abc_xyz@company.org, 另外电话: 139-8765-4321。"

# 1. match:只检查是否从开头匹配
result = re.match(r'小王的邮箱是', text)
if result:
    print("match - 匹配到字符串开头:", result.group())
else:
    print("match - 没有匹配到字符串开头")

# 2. search:查找第一个邮箱
email = re.search(r'\w+@\w+\.\w+', text)
if email:
    print("search - 第一个邮箱:", email.group())

# 3. findall:查找所有电话号码
phones = re.findall(r'\d{3}-\d{4}-\d{4}', text)
print("findall - 所有电话:", phones)

# 4. finditer:遍历所有邮箱并打印位置信息
print("finditer - 所有邮箱位置和内容:")
for match in re.finditer(r'\w+@\w+\.\w+', text):
    print(f"邮箱: {match.group()},起始: {match.start()},结束: {match.end()}")

# 5. split:按中文全角逗号和冒号分割
fragments = re.split(r'[::,,]', text)
print("split - 分割结果:", fragments)

# 6. compile:预编译正则以提高多次匹配效率
pattern = re.compile(r'\w+@\w+\.\w+')
emails = pattern.findall(text)
print("compile - 所有邮箱:", emails)

# 7. match.group()用法示例:
m = re.match(r'(\w+)的邮箱是: (\w+@\w+\.\w+)', text)
if m:
    print("match.group(0):", m.group(0))  # 整体
    print("match.group(1):", m.group(1))  # "小王"
    print("match.group(2):", m.group(2))  # 邮箱

# 8. fullmatch:判断字符串是否为合法身份证号(简单验证18位数字)
def valid_id(idstr):
    return bool(re.fullmatch(r'\d{17}[\dXx]', idstr))

print("fullmatch - 身份证:", valid_id("110101199901011234"))

# 9. sub:替换所有数字为*
anonymized = re.sub(r'\d', '*', text)
print("sub - 隐私处理后:", anonymized)

9.random - 随机数生成

9.1.功能概述

random 模块提供随机数生成和随机抽样功能,支持各种分布的随机数生成。

9.2.基本功能

9.2.1.随机数生成

import random

# 基本随机数
print("0-1随机浮点数:", random.random())
print("1-10随机整数:", random.randint(1, 10))
print("1-100随机偶数:", random.randrange(0, 101, 2))
print("5.0-10.0随机浮点数:", random.uniform(5.0, 10.0))

9.2.2.序列操作

items = ['apple', 'banana', 'cherry', 'date']

# 随机选择
print("随机选择:", random.choice(items))
print("随机选择多个:", random.choices(items, k=3))
print("随机抽样:", random.sample(items, 2))

# 打乱序列
random.shuffle(items)
print("打乱序列:", items)

9.2.3.特殊分布

# 正态分布
print("正态分布随机数:", random.gauss(0, 1))

# 设置随机种子
random.seed(42)
print("固定种子结果1:", random.randint(1, 100))
random.seed(42)
print("固定种子结果2:", random.randint(1, 100))

9.2.4.实用函数

# 生成验证码
def generate_verification_code(length=6):
    characters = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
    return ''.join(random.choices(characters, k=length))

print("验证码:", generate_verification_code())

9.3.使用场景

  • 生成验证码、密码
  • 数据分组和抽样
  • 随机事件模拟
  • 游戏开发(投骰子、抽奖)
  • 测试数据生成

9.4.注意事项

  • 加密用途请使用 secrets 模块
  • 设置种子可保证结果可重现
  • 注意随机数的分布特性

10.math - 数学运算

10.1.功能概述

math 模块提供数学计算功能,包括常量、基础数学函数、三角函数、对数函数等。

10.2.基本功能

10.2.1.常量

import math

# 数学常量
print("π的值:", math.pi)
print("e的值:", math.e)

10.2.2.基础数学函数

# 基础运算
print("平方根:", math.sqrt(16))
print("绝对值:", math.fabs(-5.5))
print("2的3次方:", math.pow(2, 3))
print("e的2次方:", math.exp(2))
print("自然对数:", math.log(10))
print("以10为底的对数:", math.log10(100))

10.2.3.三角函数

# 角度与弧度转换
angle_rad = math.radians(45)
print("45度的正弦值:", math.sin(angle_rad))
print("45度的余弦值:", math.cos(angle_rad))
print("45度的正切值:", math.tan(angle_rad))

# 反三角函数
print("反正弦:", math.degrees(math.asin(0.5)))

10.2.4.取整运算

# 取整函数
print("向上取整:", math.ceil(3.2))
print("向下取整:", math.floor(3.8))
print("四舍五入:", round(3.5))
print("截断小数:", math.trunc(3.9))

10.2.5.排列组合

# 阶乘和组合
print("5的阶乘:", math.factorial(5))
print("组合数C(5,2):", math.comb(5, 2))
print("排列数P(5,2):", math.perm(5, 2))

10.2.6.距离和统计

# 距离计算
point1 = (1, 2)
point2 = (4, 6)
distance = math.dist(point1, point2)
print("两点距离:", distance)

# 序列运算
numbers = [1, 2, 3, 4, 5]
print("总和:", math.fsum(numbers))
print("乘积:", math.prod(numbers))

10.3.使用场景

  • 科学计算和数值分析
  • 几何计算和图形处理
  • 统计分析和概率计算
  • 算法实现和优化

11.itertools - 高效迭代器

11.1.功能概述

itertools 模块提供高效的迭代器工具,支持无限序列、组合数学、多序列处理等。

11.2.主要功能

11.2.1.无限迭代器

import itertools

# 计数器
counter = itertools.count(10)
print("从10开始的计数:")
for i in range(3):
    print(next(counter))

# 循环迭代器
cycler = itertools.cycle('ABC')
print("循环重复:")
for i in range(5):
    print(next(cycler))

# 重复迭代器
repeater = itertools.repeat('hello', 3)
print("重复元素:", list(repeater))

11.2.2.有限迭代器

# 累积和
print("累积和:", list(itertools.accumulate([1, 2, 3, 4, 5])))

# 链式连接
print("链式连接:", list(itertools.chain('ABC', 'DEF')))

# 分组
data = ['A', 'A', 'B', 'C', 'C', 'C']
print("分组:")
for key, group in itertools.groupby(data):
    print(f"{key}: {list(group)}")

11.2.3.组合数学

# 排列
print("排列:", list(itertools.permutations('ABC', 2)))

# 组合
print("组合:", list(itertools.combinations('ABC', 2)))

# 带重复的组合
print("带重复的组合:", list(itertools.combinations_with_replacement('ABC', 2)))

11.2.4.多序列处理

# 并行迭代
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
for name, age in itertools.zip_longest(names, ages, fillvalue='未知'):
    print(f"{name}: {age}岁")

11.3.使用场景

  • 数据流处理
  • 组合数学计算
  • 多序列并行处理
  • 算法实现和优化

12.functools - 高阶函数工具

12.1.功能概述

functools 模块提供高阶函数工具,支持函数式编程和装饰器功能。

12.2.主要功能

12.2.1.partial - 偏函数

import functools

# 定义乘法函数
def multiply(x, y):
    return x * y

# 创建偏函数
double = functools.partial(multiply, 2)
triple = functools.partial(multiply, 3)

print("2的5倍:", double(5))
print("3的5倍:", triple(5))

12.2.2.lru_cache - 缓存装饰器

# 使用lru_cache缓存斐波那契函数
@functools.lru_cache(maxsize=128)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print("斐波那契数列:")
for i in range(10):
    print(f"F({i}) = {fibonacci(i)}")

print("缓存信息:", fibonacci.cache_info())

12.2.3.reduce - 累积运算

# 使用reduce计算列表乘积
numbers = [1, 2, 3, 4, 5]
product = functools.reduce(lambda x, y: x * y, numbers)
print("列表乘积:", product)

12.2.4.total_ordering - 自动比较

# 使用total_ordering自动补全比较方法
@functools.total_ordering
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def __eq__(self, other):
        return self.score == other.score
    
    def __lt__(self, other):
        return self.score < other.score
    
    def __repr__(self):
        return f"Student({self.name}, {self.score})"

# 创建学生对象并排序
students = [Student("Alice", 85), Student("Bob", 92), Student("Charlie", 78)]
sorted_students = sorted(students)
print("按成绩排序:", sorted_students)

12.2.5.wraps - 装饰器包装

# 使用wraps保留原函数信息
def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print(f"调用函数: {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def say_hello(name):
    """打招呼函数"""
    return f"Hello, {name}!"

print(say_hello("World"))
print("函数名:", say_hello.__name__)
print("函数文档:", say_hello.__doc__)

12.3.使用场景

  • 函数式编程
  • 性能优化(缓存)
  • 装饰器开发
  • 算法实现

下面是 functools 常用功能及应用的举例:

# 导入functools标准库模块
import functools

# 定义一个乘法函数,接收两个参数x和y,返回它们的乘积
def multiply(x, y):
    return x * y

# 创建一个偏函数double,第一个参数固定为2,实现2*x的功能
double = functools.partial(multiply, 2)
# 创建一个偏函数triple,第一个参数固定为3,实现3*x的功能
triple = functools.partial(multiply, 3)

# 输出2的5倍
print("2的5倍:", double(5))
# 输出3的5倍
print("3的5倍:", triple(5))

# 使用lru_cache装饰器,缓存最多128个fibonacci函数的结果
@functools.lru_cache(maxsize=128)
def fibonacci(n):
    # 当n小于2时直接返回n(即0或1)
    if n < 2:
        return n
    # 递归计算斐波那契数列
    return fibonacci(n-1) + fibonacci(n-2)

# 输出斐波那契数列的提示
print("斐波那契数列:")
# 计算并输出前10个斐波那契数
for i in range(10):
    print(f"F({i}) = {fibonacci(i)}")

# 输出缓存的使用信息
print("缓存信息:", fibonacci.cache_info())

# 定义一个整数列表
numbers = [1, 2, 3, 4, 5]
# 使用reduce函数和lambda表达式计算列表中所有元素的乘积
product = functools.reduce(lambda x, y: x * y, numbers)
# 输出列表的乘积
print("列表乘积:", product)

# 使用total_ordering装饰器自动补全比较方法
@functools.total_ordering
class Student:
    # 初始化学生对象,包含姓名和分数
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    # 定义等于比较方法,根据score判断
    def __eq__(self, other):
        return self.score == other.score
    
    # 定义小于比较方法,根据score判断
    def __lt__(self, other):
        return self.score < other.score
    
    # 定义对象的字符串表示
    def __repr__(self):
        return f"Student({self.name}, {self.score})"

# 创建学生对象列表
students = [Student("Alice", 85), Student("Bob", 92), Student("Charlie", 78)]
# 对学生列表按score从小到大排序
sorted_students = sorted(students)
# 输出排序后的学生列表
print("按成绩排序:", sorted_students)

# 定义一个装饰器,保留原函数信息,并在调用时打印函数名
def my_decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        # 打印被调用的函数名
        print(f"调用函数: {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

# 使用自定义装饰器装饰say_hello函数
@my_decorator
def say_hello(name):
    """打招呼函数"""
    return f"Hello, {name}!"

# 调用say_hello函数并输出结果
print(say_hello("World"))
# 输出say_hello的函数名
print("函数名:", say_hello.__name__)
# 输出say_hello的文档字符串
print("函数文档:", say_hello.__doc__)

13.typing - 类型注解

13.1.功能概述

typing 模块提供类型注解功能,支持在函数、变量、集合类型等场景中进行类型标注。

13.2.基本类型注解

13.2.1.基础类型

from typing import List, Dict, Tuple, Optional, Union, Any, Callable

# 基本类型注解
def greet(name: str) -> str:
    return f"Hello, {name}!"

# 容器类型注解
def process_scores(scores: List[int]) -> Dict[str, float]:
    return {"average": sum(scores) / len(scores)}

# 可选类型
def find_user(user_id: int) -> Optional[Dict[str, Any]]:
    if user_id == 1:
        return {"name": "Alice", "age": 25}
    return None

# 联合类型
def process_data(data: Union[str, int, List]) -> str:
    return str(data)

13.2.2.函数类型注解

# 函数类型注解
MathFunction = Callable[[float, float], float]

def calculator(a: float, b: float, operation: MathFunction) -> float:
    return operation(a, b)

13.2.3.泛型类型

from typing import TypeVar, Generic

# 定义类型变量
T = TypeVar('T')

# 泛型类
class Stack(Generic[T]):
    def __init__(self):
        self.items: List[T] = []
    
    def push(self, item: T) -> None:
        self.items.append(item)
    
    def pop(self) -> T:
        return self.items.pop()

# 使用泛型
int_stack = Stack[int]()
int_stack.push(1)
int_stack.push(2)

13.2.4.类型别名

# 类型别名
Vector = List[float]
Matrix = List[Vector]

def multiply_matrix(a: Matrix, b: Matrix) -> Matrix:
    # 矩阵乘法实现
    pass

13.2.5.复杂类型注解

# 复杂类型注解
def validate_user_data(user_data: Dict[str, Any]) -> Tuple[bool, List[str]]:
    errors = []
    
    if 'name' not in user_data or not user_data['name']:
        errors.append("姓名不能为空")
    
    if 'age' not in user_data or not isinstance(user_data['age'], int):
        errors.append("年龄必须是整数")
    
    return len(errors) == 0, errors

# 使用示例
user_data = {"name": "Alice", "age": 25}
is_valid, error_list = validate_user_data(user_data)
print(f"数据有效: {is_valid}, 错误: {error_list}")

13.3.使用场景

  • 提高代码可读性
  • 静态类型检查
  • IDE智能提示
  • 代码重构和维护

下面是一些常见用法和例子:

# 从typing模块导入常用类型注解工具
from typing import List, Dict, Tuple, Optional, Union, Any, Callable

# 定义一个基本类型注解的函数,参数name为字符串,返回值为字符串
def greet(name: str) -> str:
    return f"Hello, {name}!"

# 定义接收整数列表并返回字典的函数,统计平均分
def process_scores(scores: List[int]) -> Dict[str, float]:
    return {"average": sum(scores) / len(scores)}

# 定义查找用户的函数,返回可选的字典(如果没找到返回None)
def find_user(user_id: int) -> Optional[Dict[str, Any]]:
    if user_id == 1:
        return {"name": "Alice", "age": 25}
    return None

# 定义可以接受多种类型的参数,并统一转为字符串返回
def process_data(data: Union[str, int, List]) -> str:
    return str(data)

# 定义函数类型注解,表示接收两个float参数并返回float
MathFunction = Callable[[float, float], float]

# 定义计算器函数,接收两个浮点数和一个函数作为操作
def calculator(a: float, b: float, operation: MathFunction) -> float:
    return operation(a, b)

# 从typing模块导入类型变量和泛型基类
from typing import TypeVar, Generic

# 定义类型变量T,用于泛型
T = TypeVar('T')

# 定义支持泛型的栈结构
class Stack(Generic[T]):
    # 初始化方法,创建一个空列表用于保存元素
    def __init__(self):
        self.items: List[T] = []
    
    # 压栈方法,将元素加入栈中
    def push(self, item: T) -> None:
        self.items.append(item)
    
    # 出栈方法,将元素从栈中弹出并返回
    def pop(self) -> T:
        return self.items.pop()

# 创建一个整数类型的栈
int_stack = Stack[int]()
int_stack.push(1)
int_stack.push(2)

# 定义类型别名,Vector为浮点数列表,Matrix为若干Vector组成的列表
Vector = List[float]
Matrix = List[Vector]

# 定义矩阵相乘的函数,占位实现
def multiply_matrix(a: Matrix, b: Matrix) -> Matrix:
    # 矩阵乘法实现
    pass

# 定义一个用于验证用户数据的函数,返回一个元组(布尔值,错误信息列表)
def validate_user_data(user_data: Dict[str, Any]) -> Tuple[bool, List[str]]:
    errors = []
    
    # 检查姓名是否存在且非空
    if 'name' not in user_data or not user_data['name']:
        errors.append("姓名不能为空")
    
    # 检查年龄是否为整数类型
    if 'age' not in user_data or not isinstance(user_data['age'], int):
        errors.append("年龄必须是整数")
    
    # 返回验证结果及错误信息
    return len(errors) == 0, errors

# 准备测试数据
user_data = {"name": "Alice", "age": 25}
# 调用验证函数并获取结果
is_valid, error_list = validate_user_data(user_data)
# 打印验证结果和错误信息
print(f"数据有效: {is_valid}, 错误: {error_list}")

14.综合应用示例

本节为你演示如何将 Python 标准库的多个模块结合在一起,完成一个用户数据的综合处理示例。通过该例子你将会学到:

  • 如何使用 os 管理和创建目录结构;
  • 如何用 json 模块持久化和加载数据;
  • 如何用 datetime 处理和格式化时间;
  • 如何用 random 生成随机测试数据;
  • 怎样用 collections 里的 defaultdictCounter 等工具简化聚合和分组分析;
  • 如何把标准库的各个模块配合起来,设计更符合实际需求的数据处理逻辑。

完整流程包括:

  1. 自动生成一份用户信息的测试数据存储到 data 目录下的 users.json 文件中;
  2. 读取这份数据,并统计各年龄段人数分布(使用 Counter);
  3. 按照用户分数区间将用户分组(使用 defaultdict);
  4. 可以根据分析结果进一步扩展,比如查找最大/最小分数用户、统计近一年内注册用户等。
# 导入操作系统模块
import os
# 导入json模块用于数据序列化和反序列化
import json
# 导入datetime和timedelta用于日期处理
from datetime import datetime, timedelta
# 导入defaultdict和Counter用于数据结构
from collections import defaultdict, Counter
# 导入random模块用于生成随机数
import random

# 定义创建示例数据文件的函数
def create_sample_data():
    # 函数用途说明
    """创建示例数据文件"""
    # 生成包含10个用户的字典,每个用户有id、姓名、年龄、加入日期、分数
    data = {
        "users": [
            {
                "id": i,
                "name": f"User_{i}",
                "age": random.randint(18, 60),
                "join_date": (datetime.now() - timedelta(days=random.randint(0, 365))).strftime("%Y-%m-%d"),
                "score": random.randint(50, 100)
            }
            for i in range(1, 11)
        ]
    }
    
    # 确保data目录存在,不存在则创建
    os.makedirs('data', exist_ok=True)
    
    # 以utf-8编码写入JSON文件
    with open('data/users.json', 'w', encoding='utf-8') as f:
        json.dump(data, f, indent=2, ensure_ascii=False)
    
    # 打印数据已创建的信息
    print("示例数据已创建: data/users.json")

# 定义分析用户数据的函数
def analyze_user_data():
    # 函数用途说明
    """分析用户数据"""
    try:
        # 打开并读取data/users.json文件
        with open('data/users.json', 'r', encoding='utf-8') as f:
            data = json.load(f)
    # 文件未找到时提示用户
    except FileNotFoundError:
        print("数据文件不存在,请先运行 create_sample_data()")
        return
    # JSON数据格式出错时提示用户
    except json.JSONDecodeError:
        print("数据文件格式错误")
        return
    
    # 获取所有用户数据
    users = data['users']
    
    # 用Counter统计所有用户的年龄分布
    age_distribution = Counter(user['age'] for user in users)
    # 输出年龄分布信息
    print("\n年龄分布:")
    # 对年龄和人数按年龄从小到大输出
    for age, count in sorted(age_distribution.items()):
        print(f"  {age}岁: {count}人")
    
    # 用defaultdict按照分数段分组
    score_groups = defaultdict(list)
    for user in users:
        # 计算分数区间(如70-79)
        score_range = f"{(user['score'] // 10) * 10}-{(user['score'] // 10) * 10 + 9}"
        # 添加用户名到对应分数区间
        score_groups[score_range].append(user['name'])
    
    # 输出分数分组信息
    print("\n分数分组:")
    # 按分数区间从小到大输出分组信息
    for score_range, names in sorted(score_groups.items()):
        print(f"  {score_range}分: {', '.join(names)}")
    
    # 统计总用户数
    total_users = len(users)
    # 计算平均年龄
    avg_age = sum(user['age'] for user in users) / total_users
    # 计算平均分数
    avg_score = sum(user['score'] for user in users) / total_users
    
    # 输出摘要统计
    print(f"\n统计摘要:")
    print(f"  总用户数: {total_users}")
    print(f"  平均年龄: {avg_age:.1f}岁")
    print(f"  平均分数: {avg_score:.1f}分")

# 定义根据id获取用户信息的函数
def get_user_by_id(user_id):
    # 函数用途说明
    """根据ID获取用户信息"""
    try:
        # 打开并读取data/users.json文件
        with open('data/users.json', 'r', encoding='utf-8') as f:
            data = json.load(f)
        # 遍历所有用户
        for user in data['users']:
            # 如果id匹配,则返回该用户
            if user['id'] == user_id:
                return user
        # 未找到则返回None
        return None
    # 文件未找到则输出提示,返回None
    except FileNotFoundError:
        print("数据文件不存在")
        return None

# 定义获取分数最高用户的函数,默认取前5名
def get_top_users(limit=5):
    # 函数用途说明
    """获取分数最高的用户"""
    try:
        # 打开并读取data/users.json文件
        with open('data/users.json', 'r', encoding='utf-8') as f:
            data = json.load(f)
        # 获取所有用户数据
        users = data['users']
        # 将用户按分数降序排列,取前limit个
        top_users = sorted(users, key=lambda x: x['score'], reverse=True)[:limit]
        # 打印前top N名用户信息
        print(f"\n前{limit}名用户:")
        for i, user in enumerate(top_users, 1):
            print(f"  {i}. {user['name']} - {user['score']}分")
        # 返回最高分的用户列表
        return top_users
    # 文件未找到时输出提示,返回空列表
    except FileNotFoundError:
        print("数据文件不存在")
        return []

# 定义根据年龄范围搜索用户的函数
def search_users_by_age(min_age, max_age):
    # 函数用途说明
    """根据年龄范围搜索用户"""
    try:
        # 打开并读取data/users.json文件
        with open('data/users.json', 'r', encoding='utf-8') as f:
            data = json.load(f)
        # 获取所有用户数据
        users = data['users']
        # 按年龄范围过滤用户
        filtered_users = [user for user in users if min_age <= user['age'] <= max_age]
        # 输出筛选结果
        print(f"\n年龄在 {min_age}-{max_age} 岁的用户:")
        # 若有符合条件的用户则逐一输出
        if filtered_users:
            for user in filtered_users:
                print(f"  {user['name']} - {user['age']}岁 - {user['score']}分")
        # 否则提示没有符合条件的用户
        else:
            print("  没有找到符合条件的用户")
        # 返回符合条件的用户列表
        return filtered_users
    # 文件未找到时输出提示,返回空列表
    except FileNotFoundError:
        print("数据文件不存在")
        return []

# 只有在模块作为脚本直接运行时才执行以下代码
if __name__ == "__main__":
    # 打印分隔线
    print("=" * 50)
    # 输出系统标题
    print("用户数据分析系统")
    # 再打印分隔线
    print("=" * 50)
    
    # 创建样本数据
    create_sample_data()
    
    # 分析用户数据
    analyze_user_data()
    
    # 显示分数前5名用户
    get_top_users(5)
    
    # 按指定年龄段搜索用户
    search_users_by_age(25, 35)
    
    # 打印分析结束标志
    print("\n" + "=" * 50)
    print("分析完成!")
    print("=" * 50)
img