Python:浅谈迭代器、生成器与协程的演化路径

“人生苦短,我用Python”,虽然说大量数学和统计分析库是一个重要优势,但是归根结底,Python的最大优势就是三点:

但是通常一般来讲,当扯到并发的时候,无论是多服务器、多进程、多线程、还是协程,事情都难以避免的开始变得复杂。我们把目光放到并发的最轻量级实现:协程上面,简单浅谈一下关于迭代器。

从迭代器说起

迭代器是访问集合元素的一种方式,无需知道集合的内部结构。任何实现了__iter____next__方法的对象都是迭代器。迭代器使得你可以逐个遍历容器内的元素,直到没有更多元素时抛出StopIteration异常。可以很容易实现一个自定义迭代器,这在自己实现一些需要迭代的数据结构式会有些作用:

class MyIterator:def __init__(self, max):self.current = 0self.max = maxdef __iter__(self):return selfdef __next__(self):if self.current >= self.max:raise StopIterationvalue = self.currentself.current += 1return value# 使用迭代器
for i in MyIterator(5):print(i)

输出:

0
1
2
3
4

迭代的艺术:生成器

生成器(Generators)是Python中一种特殊的迭代器。与传统的通过列表、元组等数据结构存储所有元素不同,生成器仅在需要时生成下一个值,大大节省了内存空间。生成器自动实现了迭代器协议,使得编写迭代器更为简单且内存效率更高。

如果想要自行通过迭代器实现与生成器相同功能,也并不困难,如下例子中调用__next__方法与生成器作用类似:

class FibonacciIterator:def __init__(self, max_count):self.max_count = max_countself.current_count = 0self.prev = 0self.curr = 1def __iter__(self):return selfdef __next__(self):if self.current_count >= self.max_count:raise StopIterationelse:self.current_count += 1if self.current_count == 1:return self.prevelif self.current_count == 2:return self.currelse:self.prev, self.curr = self.curr, self.prev + self.currreturn self.curr# 使用自定义迭代器
fib_iter = FibonacciIterator(10)
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())
print(fib_iter.__next__())

输出:

0
1
1
2
3
5
8

生成器最简单的形式是使用函数定义中的yield语句。每当遇到yield,函数就会暂停并返回一个值给调用者;当再次调用生成器的next()方法时,它会从上次停止的地方继续执行。上面的迭代器程序略显复杂,但是使用生成器之后,程序则变得简单清晰的多。下面的例子使用生成器实现了一样的功能,这可以很好的帮助理解迭代器的运行顺序:


def fibonacci_generator(max_count):prev, curr = 0, 1count = 0while count < max_count:yield prevprev, curr = curr, prev + currcount += 1# 使用生成器
for num in fibonacci_generator(10):print(num)

输出:

0
1
1
2
3
5
8
13
21
34

Python的协程

在Python中,协程(Coroutines)通常被认为是生成器(Generators)的一个超集。它利用生成器的暂停与恢复机制,实现了非阻塞式的并发执行。协程在生成器的基础上进行了扩展,增加了更多的控制流特性,如能够接收输入、暂停执行等。协程是通过生成器实现的,生成器中的yield关键字可以用来实现协程的暂停和恢复执行的功能。Python协程实现,会使用asyncio包,并配合async/await语法糖。

可能只是我个人的YY,似乎Python的协程或多或少的借鉴了JS。从语法到实现方式都非常类似。在现代ES中,async/await语法糖是必不可少,几乎每个程序都会用到的,而Python也是用相同的关键字,从标准化角度,JS先于Python标准化了这两个语法糖。

一个简单的Python使用asyncio的例子如下所示:

import asyncioasync def task(name, delay):print(f"{name} start")await asyncio.sleep(delay)print(f"{name} end")async def main():task1 = asyncio.create_task(task("TAsk1", 2))task2 = asyncio.create_task(task("TaSK2", 1))await task1await task2asyncio.run(main()

输出:

TAsk1 start
TaSK2 start
TaSK2 end
TAsk1 end

上面代码中,通过asyncio.create_task创建了两个小任务,任务是异步运行的,并且程序必须等待两个任务都结束后,main才会返回。注意这里asyncio.create_task创建的task有些类似于JS的:

new Promise().then()

所以两个task是异步的。如果希望等待Task1完成后再运行Task2,则不需要通过asyncio.create_task创建task,直接再async函数调用前加入await即可,这是JS中一个常用的写法。如下:

import asyncioasync def main():await task("TAsk1", 2)await task("TaSK2", 1)asyncio.run(main())

输出:

TAsk1 start
TAsk1 end
TaSK2 start
TaSK2 end

总结

从迭代器,到生成器,最后到协程,理解这个演化路径,可以更好地理解Python的协程机制。在此之后,加上对asyncio库的了解,即可熟练掌握Pythong的协程机制了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/35064.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C# SocketUDP服务器,组播

SocketUDP 自己即是服务器又是客户端 &#xff0c;在发消息只需要改成对方ip和端口号即可 前提对方必须开启服务器 socket.Bind(new IPEndPoint(IPAddress.Parse("192.168.107.72"), 8080)); 控件&#xff1a;Button,TextBox,RichTextBox 打开自己服务器 public…

【操作系统】信号处理与阻塞函数|时序竞态问题

&#x1f525;博客主页&#xff1a; 我要成为C领域大神&#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 ​ 关于阻塞函数和…

Windows环境部署MySQL_8.4.0 LTS的部署安装、验证连接以及卸载全过程实操手册

前言&#xff1a; 什么是 MySQL MySQL 是一个关系型数据库管理系统&#xff0c;由瑞典 MySQL AB 公司开发&#xff0c;目前属于Oracle 公司。MySQL 是一种关系型数据库管理系统&#xff0c;关系型数据库将数据保存在不同的表中&#xff0c;而不是将所有数据放在一个大仓库内&am…

8.12 矢量图层面要素单一符号使用七(随机标记填充)

文章目录 前言随机标记填充&#xff08;Random Marker Fill&#xff09;QGis设置面符号为随机标记填充&#xff08;Random Marker Fill&#xff09;二次开发代码实现随机标记填充&#xff08;Random Marker Fill&#xff09; 总结 前言 本章介绍矢量图层线要素单一符号中使用随…

分班查询怎么发布?

在现代教育环境中&#xff0c;传统的学生分班通知方式可能显得有些过时和低效。通常&#xff0c;这些方式依赖于纸质通知单&#xff0c;这不仅需要大量的物理资源进行打印和分发&#xff0c;而且容易出错&#xff0c;如丢失、错误分发或延迟。 幸运的是&#xff0c;现在有了更高…

心灵馆咨询系统小程序心理咨询平台聊天咨询

心灵馆咨询系统小程序&#xff1a;解锁你的心灵密码 &#x1f496; 心灵之旅的导航者 在繁忙的现代生活中&#xff0c;我们时常会面临各种压力与困惑。心灵馆咨询系统小程序&#xff0c;如同一位贴心的导航者&#xff0c;引领我们探索内心的世界&#xff0c;寻找真正的自我。 …

shell 脚本的部分指令和操作符

终端输入两个数&#xff0c;判断两数是否相等&#xff0c;如果不相等&#xff0c;判断大小关系 2.已知网址www.hqyj.com&#xff0c;使用expr截取出www、hqyj、com&#xff0c;不能使用cut&#xff0c;不能出现数字

JavaWeb系列十九: jQuery的DOM操作 上

查找节点, 修改属性 查找属性节点: 查找到所需要的元素之后, 可以调用jQuery对象的attr()方法用来 设置/返回 它的各种属性值 设置属性值 $(“img”).attr(“width”, “300”);返回属性值 $(“img”).attr(“width”); 创建节点 创建节点: 使用jQuery的工厂函数$(): $(html标…

硬核实力再亮,玩出梦想科技发布全球首款安卓系统空间计算机

6月25日&#xff0c;玩出梦想科技在新加坡召开全球新品发布会&#xff0c;正式发布全球首款安卓系统空间计算机——玩出梦想MR&#xff0c;填补了空间计算机在安卓生态的空白。 作为品牌沉淀两年的破晓之作&#xff0c;玩出梦想MR以业内领先软硬件配置&#xff0c;强大自研算法…

解决了!暗影精灵8 Pro酷睿版无声音,扬声器和麦克风都没有声音!

困扰好几天的问题解决了&#xff01; 暗影精灵8 Pro酷睿版无声音&#xff0c;扬声器和麦克风都没有声音&#xff01;&#xff01;方法适用于OMEN by HP Gaming Laptop 16-k0xxx&#xff08;暗影精灵8 Pro酷睿版&#xff09;的Windows 10声卡驱动&#xff01; 朋友们&#xff…

【应用开发一】LED开发

文章目录 1应用层控制外设的两种方式2 sysfs和/sys关系3 LED控制方式3.1 基本情况3.2 LED属性文件介绍3.3 命令行属性测试3.4 led程序3.5 开发板上测试 1应用层控制外设的两种方式 使用设备文件控制 在Linux系统下&#xff0c;一切皆是文件。应用层控制底层硬件同样也是通过文…

第100+12步 ChatGPT学习:R实现KNN分类

基于R 4.2.2版本演示 一、写在前面 有不少大佬问做机器学习分类能不能用R语言&#xff0c;不想学Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi转一下就得了呗。 加上最近也没啥内容写了&#xff0c;就帮各位搬运一下吧。 二、R代码实现KNN分类 &#xff08;1&a…

【Docker】Consul 和API

目录 一、Consul 1. 拉取镜像 2. 启动第一个consul服务&#xff1a;consul1 3. 查看consul service1 的ip地址 4. 启动第二个consul服务&#xff1a;consul2&#xff0c; 并加入consul1&#xff08;使用join命令&#xff09; 5. 启动第三个consul服务&#xff1a;consul3&…

攻击者开始使用 XLL 文件进行攻击

近期&#xff0c;研究人员发现使用恶意 Microsoft Excel 加载项&#xff08;XLL&#xff09;文件发起攻击的行动有所增加&#xff0c;这项技术的 MITRE ATT&CK 技术项编号为 T1137.006。 这些加载项都是为了使用户能够利用高性能函数&#xff0c;为 Excel 工作表提供 API …

【SQL Server数据库】关系模式与关系代数

目录 一、请用关系代数完成下列查询 1. 求 供应工程J1 零件P1的供应商号码SNO&#xff1b; 2. 求 供应工程J1 零件&#xff08;P&#xff09;为红色 的供应商号码SNO&#xff1b; 3. 求 没有使用 天津供应商&#xff08;P&#xff09;生产的红色零件&#xff08;S&#xff0…

pycharm中的使用技巧

1、更改主题&#xff1a;找到设置&#xff0c;然后更改主题 点击选择自己喜欢的主题&#xff0c;然后就可以更改主题了 2、设置字体的快捷键 找到设置&#xff0c;如下&#xff1a; 找到increase&#xff0c;如下&#xff1a; 右键选择&#xff0c;增加字体快捷键 按住ctrl滑轮…

Excel 查找后隐去右边列

Excel 有几列数字 ABC11002042002202100102326027010841199100512100100 当给定参数时&#xff0c;请从每行找到该参数&#xff0c;隐去右边的列。如果某行不含该参数&#xff0c;则隐去整行。当参数是 100 时&#xff0c;结果如下&#xff1a; ABC710082021009119910010121…

shell之免交互

免交互 交互&#xff1a;发出指令控制指令的运行&#xff0c;程序再接收到指令的效果做出对应的反应。 免交互&#xff1a;间接的&#xff0c;通过第三方的方式把指令传送给程序&#xff0c;不用直接的下达指令 Hhere Document 免交互 这是命令行格式&#xff0c;也可以写在脚本…

QTableWidget的使用

使用QTableWidget&#xff0c;初始化数据、设置列头及格式&#xff0c;设置行数&#xff0c;设置每个单元格的编辑&#xff0c;间隔行底色变换、行选择 &#xff0c;模式&#xff0c;单元格选择模式、插入行 、追加行、删除行&#xff0c;单元格加图标&#xff0c;单元格显示ch…