我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Python3.10 Generator生成器Coroutine原生协程详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Python3.10 Generator生成器Coroutine原生协程详解

引言

普遍意义上讲,生成器是一种特殊的迭代器,它可以在执行过程中暂停并在恢复执行时保留它的状态。而协程,则可以让一个函数在执行过程中暂停并在恢复执行时保留它的状态,在Python3.10中,原生协程的实现手段,就是生成器,或者说的更具体一些:协程就是一种特殊的生成器,而生成器,就是协程的入门心法。

协程底层实现

我们知道,Python3.10中可以使用async和await关键字来实现原生协程函数的定义和调度,但其实,我们也可以利用生成器达到协程的效果,生成器函数和普通函数的区别在于,生成器函数使用 yield 语句来暂停执行并返回结果。例如,下面是一个使用生成器函数实现的简单协程:

def my_coroutine():  
    while True:  
        x = yield  
        print(x)  
# 使用生成器函数创建协程  
coroutine = my_coroutine()  
# 启动协程  
next(coroutine)  
# 在协程中传入数据  
coroutine.send(1)  
coroutine.send(2)  
coroutine.send(3)

程序返回:

➜  mydemo git:(master) ✗ /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/mydemo/class="lazy" data-src/test.py"  
1  
2  
3

在上面的代码中,生成器函数 my_coroutine 使用了一个无限循环来实现协程的逻辑。每当调用 send 方法时,协程就会从 yield 语句处恢复执行,并将传入的参数赋值给变量 x。

如此,就完成了协程执行-》阻塞-》切换-》回调的工作流模式。

当然,作为事件循环机制,协程服务启动可能无限期地运行,要关闭协程服务,可以使用生成器的close()方法。当一个协程被关闭时,它会生成GeneratorExit异常,该异常可以用生成器的方式进行捕获:

def my_coroutine():  
    try :  
        while True:  
            x = yield  
            print(x)  
    except GeneratorExit:  
            print("协程关闭")  
# 使用生成器函数创建协程  
coroutine = my_coroutine()  
# 启动协程  
next(coroutine)  
# 在协程中传入数据  
coroutine.send(1)  
coroutine.send(2)  
coroutine.send(3)  
coroutine.close()

程序返回:

➜  mydemo git:(master) ✗ /opt/homebrew/bin/python3.10 "/Users/liuyue/wodfan/work/mydemo/class="lazy" data-src/test.py"  
1  
2  
3  
协程关闭

业务场景

在实际业务场景中,我们也可以使用生成器来模拟协程流程,主要体现在数据的IO流操作中,假设我们需要从本地往服务器传输数据,首先建立链接对象:

class Connection:  
    def __init__(self, addr):  
        self.addr = addr  
    def transmit(self, data):  
        print(f"X: {data[0]}, Y: {data[1]} sent to {self.addr}")

随后建立生成器函数:

def send_to_server(conn):  
    while True:  
        try:  
            raw_data = yield  
            raw_data = raw_data.split(' ')  
            coords = (float(raw_data[0]), float(raw_data[1]))  
            conn.transmit(coords)  
        except ConnectionError:  
            print("链接丢失,进行回调")  
            conn = Connection("重新连接v3u.cn")

利用生成器调用链接类的transmit方法进行数据的模拟传输,如果链接断开,则会触发回调重新连接,执行逻辑:

if __name__ == '__main__':  
    conn = Connection("v3u.cn")  
    sender = send_to_server(conn)  
    sender.send(None)  
    for i in range(1, 6):  
        sender.send(f"{100/i} {200/i}")  
    # 模拟链接断开  
    conn.addr = None  
    sender.throw(ConnectionError)   
    for i in range(1, 6):  
        sender.send(f"{100/i} {200/i}")

程序返回:

X: 100.0, Y: 200.0 sent to v3u.cn  
X: 50.0, Y: 100.0 sent to v3u.cn  
X: 33.333333333333336, Y: 66.66666666666667 sent to v3u.cn  
X: 25.0, Y: 50.0 sent to v3u.cn  
X: 20.0, Y: 40.0 sent to v3u.cn  
链接丢失,进行回调  
X: 100.0, Y: 200.0 sent to 重新连接v3u.cn  
X: 50.0, Y: 100.0 sent to 重新连接v3u.cn  
X: 33.333333333333336, Y: 66.66666666666667 sent to 重新连接v3u.cn  
X: 25.0, Y: 50.0 sent to 重新连接v3u.cn  
X: 20.0, Y: 40.0 sent to 重新连接v3u.cn

如此,我们就可以利用生成器的“状态保留”机制来控制网络链接突然断开的回调补救措施了。

所以说,协程就是一种特殊的生成器:

async def test():  
    pass  
print(type(test())) 

您猜怎么着?

<class 'coroutine'>

结语

诚然,生成器和协程也并非完全是一个概念,与生成器不同的是,协程可以被另一个函数(称为调用方)恢复执行,而不是只能由生成器本身恢复执行。这使得协程可以用来实现更复杂的控制流,因为它们可以在执行时暂停并在任意时刻恢复执行。

以上就是Python3.10 Generator生成器Coroutine原生协程详解的详细内容,更多关于Python生成器原生协程的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Python3.10 Generator生成器Coroutine原生协程详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Python3.10 Generator生成器Coroutine原生协程详解

这篇文章主要为大家介绍了Python3.10 Generator生成器Coroutine原生协程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-28

5.6 Mybatis代码生成器Mybatis Generator (MBG)实战详解

文章目录 前言一、Mybatis Generator简介二、Maven插件运行方式三、生成配置 generatorConfig.xmlMyBatis3Simple风格MyBatis3风格MyBatis3DynamicSql风格
2023-08-17

浅谈Python生成器generator之next和send的运行流程(详解)

对于普通的生成器,第一个next调用,相当于启动生成器,会从生成器函数的第一行代码开始执行,直到第一次执行完yield语句(第4行)后,跳出生成器函数。 然后第二个next调用,进入生成器函数后,从yield语句的下一句语句(第5行)开始执
2022-06-04

只要3分钟,Python生成器原理详解

翻译:你逗比segmentfault.com/a/1190000011330511这篇文章是对 500 Lines or Less 一书中高效爬虫一章的部分翻译,原文:How Python Generators Work。建议结合《流畅的
2023-01-31

MyBatisPlus代码生成器的原理及实现详解

这篇文章主要为大家详细介绍了MyBatisPlus中代码生成器的原理及实现,文中的示例代码讲解详细,对我们学习MyBatisPlus有一定帮助,需要的可以参考一下
2022-11-13

详解JS前端使用迭代器和生成器原理及示例

这篇文章主要为大家介绍了详解JS前端使用迭代器和生成器原理及示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-21

Dart 异步编程生成器及自定义类型用法详解

这篇文章主要为大家介绍了Dart 异步编程生成器及自定义类型用法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-11-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录