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

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.xdnf.cn/news/18481.html

相关文章:

  • 阿里云搭建flask服务器
  • 【C++】类和对象——默认成员函数(中)(附思维导图)
  • .NET Core MongoDB 查询数据异常及解决
  • 2 Nacos 集群的数据同步机制
  • 服务发现与负载均衡:Kubernetes Service核心机制深度解析
  • 在Excel和WPS表格中合并多个单元格这样最快
  • Web15- Java Web安全:防止XSS与CSRF攻击
  • 银河麒麟V10系统离线安装zabbix-agent教程
  • 机器学习3
  • 使用WORD实现论文格式的样式化制作【标题样式、自动序列、页号(分节)、自动目录(修改字体类型)】
  • P4175 [CTSC2008] 网络管理 Solution
  • vulhub可用的docker源
  • Python 数据可视化:Matplotlib 与 Seaborn 实战
  • 鸿蒙中网络诊断:Network分析
  • 深度解析:RESTful API中的404错误 - 不是所有404都是Bug
  • stm32学习详细笔记001
  • C++/Qt开发:TCP通信连接软件测试方法:ECHO指令
  • Linux系统:C语言进程间通信信号(Signal)
  • 【网络运维】Linux 文本搜索利器: grep命令
  • Linux-文本搜索工具grep
  • RHCA07-Linux跟踪工具及CPU调优
  • 详解flink table api基础(三)
  • 在Excel和WPS表格中制作可打印的九九乘法表
  • 服务器内存使用buff/cache的原理
  • 单片机驱动继电器接口
  • 图论Day6学习心得
  • 动态规划----8.乘积最大子数组
  • 从“怀疑作弊”到“实锤取证”:在线面试智能监考重塑招聘公信力
  • CMake1:概述
  • 通过自动化本地计算磁盘与块存储卷加密保护数据安全