当前位置: 首页 > news >正文

2025-08-21 Python进阶6——迭代器生成器与with

文章目录

  • 1 迭代器与生成器
    • 1.1 迭代器
      • 1.1.1 基本使用
      • 1.1.2 手动迭代(带异常处理)
      • 1.1.3 自定义迭代器
    • 1.2 生成器
      • 1.2.1 工作原理
      • 1.2.2 斐波那契数列示例
    • 1.3 推导式
      • 1.3.1 列表推导式
      • 1.3.2 字典推导式
      • 1.3.3 集合推导式
      • 1.4.4 元组推导式(生成器表达式)
  • 2 with关键字
    • 2.1 基本语法
    • 2.2 常用场景
      • 2.2.1 文件操作(最典型)
      • 2.2.2 数据库连接
      • 2.2.3 线程锁
    • 2.3 工作原理:上下文管理协议
    • 2.4 自定义上下文管理器
      • 2.4.1 方式 1:类实现
      • 2.4.2 方式 2:使用 contextlib 模块
    • 2.5 最佳实践

1 迭代器与生成器

1.1 迭代器

  • 迭代器是可记住遍历位置的对象
  • 只能向前遍历,不能后退
  • 核心方法:iter() 创建迭代器,next() 获取下一个元素

1.1.1 基本使用

# 创建迭代器
list = [1, 2, 3, 4]
it = iter(list)  # 创建迭代器对象# 访问元素
print(next(it))  # 1
print(next(it))  # 2# 使用for循环遍历
for x in it:print(x, end=" ")  # 3 4

1.1.2 手动迭代(带异常处理)

import sysit = iter([1, 2, 3, 4])while True:try:print(next(it))except StopIteration:sys.exit()  # 迭代结束时退出

1.1.3 自定义迭代器

需实现两个方法:

  • __iter__(): 返回迭代器对象本身
  • __next__(): 返回下一个元素,迭代结束时抛出StopIteration
class MyNumbers:def __iter__(self):self.a = 1return selfdef __next__(self):if self.a <= 20:  # 限制迭代次数x = self.aself.a += 1return xelse:raise StopIteration  # 结束迭代# 使用自定义迭代器
myclass = MyNumbers()
for x in iter(myclass):print(x)  # 输出1到20

1.2 生成器

  • 使用yield关键字的函数称为生成器
  • 生成器是特殊的迭代器,可逐步产生值
  • 调用生成器函数返回的是迭代器对象

1.2.1 工作原理

  • 执行到yield时返回值并暂停
  • 下次调用时从暂停处继续执行
  • 适合处理大量数据或无限序列
def countdown(n):while n > 0:yield n  # 返回当前值并暂停n -= 1# 使用生成器
generator = countdown(5)
print(next(generator))  # 5
print(next(generator))  # 4# 用for循环迭代剩余值
for value in generator:print(value)  # 3 2 1

1.2.2 斐波那契数列示例

def fibonacci(n):a, b, counter = 0, 1, 0while True:if counter > n:returnyield a  # 返回当前斐波那契数a, b = b, a + bcounter += 1# 使用生成器
f = fibonacci(10)
for x in f:print(x, end=" ")  # 0 1 1 2 3 5 8 13 21 34 55

1.3 推导式

推导式是一种简洁的数据处理语法,可从一个序列构建新序列,支持列表、字典、集合和元组。

1.3.1 列表推导式

格式[表达式 for 变量 in 列表 if 条件]

实例 1:过滤并转换

names = ['Bob','Tom','alice','Jerry','Wendy','Smith']
new_names = [name.upper() for name in names if len(name) > 3]
# 结果: ['ALICE', 'JERRY', 'WENDY', 'SMITH']

实例 2:数值筛选

multiples = [i for i in range(30) if i % 3 == 0]
# 结果: [0, 3, 6, 9, 12, 15, 18, 21, 24, 27]

1.3.2 字典推导式

格式{key表达式: value表达式 for 变量 in 集合 if 条件}

实例 1:字符串长度字典

listdemo = ['Google','Runoob', 'Taobao']
newdict = {key: len(key) for key in listdemo}
# 结果: {'Google': 6, 'Runoob': 6, 'Taobao': 6}

实例 2:数字平方字典

dic = {x: x**2 for x in (2, 4, 6)}
# 结果: {2: 4, 4: 16, 6: 36}

1.3.3 集合推导式

格式{表达式 for 变量 in 序列 if 条件}

实例 1:计算平方

setnew = {i**2 for i in (1, 2, 3)}
# 结果: {1, 4, 9}

实例 2:字符筛选

a = {x for x in 'abracadabra' if x not in 'abc'}
# 结果: {'d', 'r'}

1.4.4 元组推导式(生成器表达式)

格式(表达式 for 变量 in 序列 if 条件)
注意:返回生成器对象,需用tuple()转换

实例:生成数字元组

a = (x for x in range(1, 10))  # 生成器对象
print(tuple(a))  # 转换为元组
# 结果: (1, 2, 3, 4, 5, 6, 7, 8, 9)

2 with关键字

with 关键字用于上下文管理,简化资源(如文件、数据库连接)的获取与释放,确保资源使用后被正确清理。

对比传统资源管理方式:

传统方式(try-finally)with 语句
需手动调用 close()自动释放资源
代码冗长简洁直观
易遗漏关闭操作异常安全

传统文件操作示例

file = open('test.txt', 'r')
try:content = file.read()
finally:file.close()  # 必须手动关闭

2.1 基本语法

with 表达式 [as 变量]:# 代码块(使用资源)
  • 表达式返回上下文管理器对象
  • as 变量:可选,将对象赋值给变量
  • 代码块执行完毕后,自动触发资源清理

2.2 常用场景

2.2.1 文件操作(最典型)

# 读取文件
with open('example.txt', 'r') as file:content = file.read()print(content)
# 退出代码块后,文件自动关闭# 同时操作多个文件
with open('in.txt', 'r') as infile, open('out.txt', 'w') as outfile:outfile.write(infile.read().upper())  # 转换为大写并写入

2.2.2 数据库连接

import sqlite3with sqlite3.connect('mydb.db') as conn:cursor = conn.cursor()cursor.execute('SELECT * FROM users')print(cursor.fetchall())
# 连接自动关闭,无需手动调用 close()

2.2.3 线程锁

import threadinglock = threading.Lock()with lock:# 临界区代码(自动加锁/解锁)print("线程安全的操作")

2.3 工作原理:上下文管理协议

支持 with 的对象需实现两个方法:

  • __enter__():进入上下文时调用,返回值赋给 as 后的变量
  • __exit__():退出上下文时调用,负责资源清理

执行流程

  1. 执行表达式,获取上下文管理器
  2. 调用 __enter__() 方法,进入上下文
  3. 执行代码块
  4. 无论是否发生异常,都调用 __exit__() 方法

异常处理机制

__exit__() 方法接收三个参数:exc_type(异常类型)、exc_val(异常值)、exc_tb(追踪信息)

  • 返回 True:表示异常已处理,不再传播
  • 返回 False/None:异常继续向外传播

2.4 自定义上下文管理器

2.4.1 方式 1:类实现

class Timer:def __enter__(self):import timeself.start = time.time()return self  # 可通过 as 接收def __exit__(self, exc_type, exc_val, exc_tb):import timeprint(f"耗时: {time.time() - self.start:.2f}秒")return False  # 不抑制异常# 使用
with Timer() as t:sum(range(10000000))  # 执行耗时操作

2.4.2 方式 2:使用 contextlib 模块

from contextlib import contextmanager@contextmanager
def tag(name):print(f"<{name}>")  # __enter__ 部分yield  # 暂停,执行代码块print(f"</{name}>")  # __exit__ 部分# 使用
with tag("h1"):print("这是标题内容")# 输出:
# <h1>
# 这是标题内容
# </h1>

2.5 最佳实践

  1. 优先使用 with:处理文件、网络连接、锁等资源时,必用 with
  2. 精简代码块with 内只写与资源相关的操作
  3. 多资源管理:一个 with 可同时管理多个资源(用逗号分隔)
  4. 异常处理:自定义上下文时,明确是否需要抑制异常

with 语句通过自动化资源管理,大幅提升了代码的可读性和可靠性,是 Python 中处理资源的首选方式。

http://www.dtcms.com/a/342277.html

相关文章:

  • Python项目开发- 动态设置工作目录与模块搜索路径
  • strerror和perror函数的使用及其联系和区别
  • 43-Python基础语法-3
  • QWidget/QMainWindow与QLayout的布局
  • CSDN使用技巧
  • Pandas中数据分组进阶以及数据透视表
  • 链表-143.重排链表-力扣(LeetCode)
  • 微信小程序集成vant-weapp时,构建npm报错的解决办法
  • 基于springboot的中医养生管理系统
  • Pytorch基础学习--张量(生成,索引,变形)
  • 火语言 RPA 进阶功能:让自动化更实用​
  • 交易高光时刻-01
  • SOP到自动化:一种适合小型金融机构的轻量级开源工具整合方案
  • Vue3+Spring Boot技术栈,前端提交混合表单数据(普通字段+文件字段),上传文件,后端插入数据,将文件保存到数据库
  • Docker端口映射与数据卷完全指南
  • 几张PPT快速了解云原生与华为云CCE方案
  • Eureka和Nacos的原理分析
  • openEuler系统中r如何将docker安装在指定目录
  • CentOS 7常用国内源配置:阿里云、腾讯云、华为云、清华源
  • 从聚类到集成,两种实用算法框架分享
  • 医疗信息化自主可控转型的实践探索 —— 以常德二院为例
  • 为什么调用API总返回404,该如何调试
  • 35、自主移动机器人 (AMR) 调度模拟 (电子厂) - /物流与仓储组件/amr-scheduling-electronics
  • 机器学习-集成算法
  • HarmonyOS 时钟应用开发详解:从零构建实时时钟组件
  • MS17-010永恒之蓝复现
  • Prometheus+Grafana 监控体系搭建:从入门到告警配置
  • open3d-点云函数:变换:旋转,缩放、平移,齐次变换(R,T)等
  • 从“卡脖子”到“自主可控”!电科金仓+东华医为生态协同,打造医疗新范式
  • postman接口自动化测试