Python生成器详解:定义、使用和注意事项

119 篇文章 1 订阅
46 篇文章 0 订阅

前言

生成器是Python中非常有用的一种迭代器(迭代器和生成器有何区别,后续详解),其可以实现惰性计算和节省内存的特性。

本文将深入讲解生成器的定义、使用和注意事项,并附有实用的示例代码。

一、生成器的定义

生成器是一种能够实现惰性计算、延迟执行和节省内存的迭代器。在Python中,通过yield语句实现生成器。

在这里插入图片描述

生成器中的函数不是直接返回一个值,而是返回一个生成器对象。取值时,通过next()方法或for循环操作获取生成器对象中的值。

二、生成器的使用场景

生成器适合于处理大数据量和耗时操作的场景,例如遍历文件或网络数据流、CPU密集型计算、图像处理等。生成器可以逐个读取大文件,并且不必将整个文件加载到内存中,避免了内存消耗和IO操作的额外开销。

三、如何定义生成器

生成器可以使用多种方式进行定义,包括通过函数、生成器类以及生成器表达式等。

1. 使用函数实现生成器

使用函数实现生成器是一种常见的方式,示例如下:

def fib(max):a, b = 0, 1while a < max:yield aa, b = b, a + bfor n in fib(1000):print(n, end=“,”)

其中,使用yield语句实现惰性计算,返回一个生成器对象。在for循环中迭代生成器对象输出斐波那契数列。

2. 使用生成器类实现生成器

使用生成器类可以实现更为复杂的生成器,例如在遍历数据库查询结果时,需要返回多个字段。示例如下:

class QueryResutl:def init(self):self.items = []self.index = 0def query(self):while True:if self.index >= len(self.items):raise StopIterationresult = self.items[self.index]self.index += 1yield resultdef add(self, item):self.items.append(item)

上述案例中,QueryResutl类包含了一个items列表和一个索引index,通过query()方法实现返回一个生成器对象。在add()方法中添加新的元素,query()方法中使用yield语句实现惰性计算和延迟执行。

3. 使用生成器表达式实现生成器

生成器表达式是一种简洁、方便的生成器定义方式,其语法类似于列表推导式。示例如下:

gen = (i ** 2 for i in range(1, 10))for n in gen:print(n, end=“,”)

其中,使用生成器表达式定义了一个生成器对象gen,包含1~9的平方值,并迭代输出结果。

四、生成器实现简单的异步操作和携程调度

下面是一个用生成器实现异步操作和携程调度的简单案例,供参考:

import timedef task1():while True:print(“task 1”)yieldtime.sleep(1)def task2():while True:print(“task 2”)yieldtime.sleep(1)def main():t1 = task1()t2 = task2()while True:next(t1)next(t2)if name == “main”:main()

在这里插入图片描述

运行效果

在上述代码中,我们定义了两个任务函数task1和task2,它们都采用了生成器的形式。每个生成器循环调用时,打印当前任务的名称,然后暂停1秒钟。在main()函数中,我们通过创建两个任务的生成器t1和t2,依次轮流执行它们,来模拟异步操作和携程调度。

在这里插入图片描述

我们运行上述程序后可以看到,输出结果会交替显示 “task 1” 和 “task 2”,说明两个任务在进行携程调度,而且不会阻塞程序的执行。

在这里插入图片描述

需要注意的是,生成器的yield语句实现了协程的特性,它取决于next()方法来驱动生成器函数的执行。因此,在main()函数中先执行t1的next()方法,再执行t2的next()方法,反复循环调度任务。

当然,也可以使用asyncio库等更高级的工具来实现异步操作和协程调度。

五、使用生成器注意事项

Python生成器是一种非常实用的编程技巧,可以实现惰性计算、延迟执行和节省内存等特性。但使用时需要注意下面几点:

生成器中的函数不会一次性执行完,而是通过yield语句实现惰性计算。对于一些需要及时释放资源的操作,应在代码中显式调用close()方法,以释放内存。yield语句中的表达式计算结果不会直接返回,而是暂停函数的执行,并返回生成器对象,等待下个next()方法或for循环的调用。生成器可以实现迭代器的所有功能,包括__next__()和__iter__()方法。可以通过使用__iter__()方法返回自身实例来实现无限迭代器。(后续介绍)生成器可以实现协程的功能,用于异步操作和携程调度。

通过准确地使用生成器,可以极大地提高程序的效率和可读性。怎么样,这个技能你GET到了吗?

-END-


Python入门全套学习资料附带源码:

全套软件安装包

附带完整的安装包的安装视频教程资源(新手大礼包已备好文末领取

在这里插入图片描述

整套零基础入门视频+课件笔记

img

👉实战案例👈

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

👉100道Python练习题👈

检查学习结果。

👉面试刷题👈

在这里插入图片描述

资料领取

上述这份完整版的Python全套学习资料已经上传网盘,朋友们如果需要可以微信扫描下方二维码输入“领取资料” 即可自动领取
或者

点此链接】领取

  • 21
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值