原来Python的协程有2种实现方式

什么是协程

在 Python 中,协程(Coroutine)是一种轻量级的并发编程方式,可以通过协作式多任务来实现高效的并发执行。协程是一种特殊的生成器函数,通过使用 yield 关键字来挂起函数的执行,并保存当前的执行状态。协程的执行可以通过 send 方法来恢复,并在下一次挂起时返回一个值。

在 Python 3.4 之前,协程通常使用 yield 关键字来实现,称为“生成器协程”。在 Python 3.4 引入了 asyncio 模块后,可以使用 async/await 关键字来定义协程函数,称为“原生协程”。

协程相比于线程和进程,具有以下优点:

  1. 轻量级:协程的上下文切换成本很小,可以在单线程内并发执行大量的协程。
  2. 低延迟:协程的执行过程中,没有线程切换的开销,也没有加锁解锁的开销,可以更快地响应外部事件。
  3. 高效性:协程的代码通常比多线程和多进程的代码更加简洁和可读,维护成本更低。

协程的使用场景包括网络编程、异步 I/O、数据流处理、高并发任务等。

生成器协程

在 Python 3 中,生成器协程(Generator Coroutine)是指使用生成器函数来实现的协程。生成器函数是一种特殊的函数,其返回一个生成器对象,可以通过 yield 语句暂停函数的执行,然后在下一次调用生成器对象的 「next」() 方法时继续执行。

下面给出一个简单的生成器协程的示例,其中包含一个生成器函数 coroutine 和一个简单的异步 I/O 操作:

import asynciodef coroutine():print('Coroutine started')while True:result = yieldprint('Coroutine received:', result)async def main():print('Main started')c = coroutine()next(c)c.send('Hello')await asyncio.sleep(1)c.send('World')print('Main finished')asyncio.run(main())

结果输出:

[root@workhost k8s]# python3 test.py 
Main started
Coroutine started
Coroutine received: Hello
Coroutine received: World
Main finished

来看一下,上面代码的执行过程:

  1. main 函数开始执行,打印出 Main started。
  2. 创建一个生成器对象 c,调用 next© 使其执行到第一个 yield 语句处暂停。
  3. 使用 c.send(‘Hello’) 恢复生成器函数的执行,并将 ‘Hello’ 作为生成器函数的返回值。
  4. 在等待1秒钟的过程中,main 函数暂停执行,等待事件循环发起下一次任务。
  5. 在等待1秒钟后,使用 c.send(‘World’) 继续执行生成器函数,并将 ‘World’ 作为生成器函数的返回值。
  6. main 函数恢复执行,打印出 Main finished。

在上面的代码中,使用生成器函数 coroutine 实现了一个简单的协程。生成器函数通过使用 yield 语句暂停函数的执行,然后可以通过 send 方法恢复函数的执行,并将值传递给生成器函数。通过这种方式,可以使用生成器函数实现异步并发。在上面的示例中,使用生成器函数接收并打印异步 I/O 操作的结果。

原生协程

Python 3 引入了原生协程(Native Coroutine)作为一种新的协程类型。原生协程是通过使用 async/await 关键字来定义的,与生成器协程不同,它们可以像普通函数一样使用 return 语句返回值,而不是使用 yield 语句。

下面给出一个简单的原生协程示例,其中包含一个 async 关键字修饰的协程函数 coroutine 和一个简单的异步 I/O 操作:

import asyncioasync def coroutine():print('Coroutine started')await asyncio.sleep(1)print('Coroutine finished')async def main():print('Main started')await coroutine()print('Main finished')asyncio.run(main())

结果输出:

[root@workhost k8s]# python3 test.py 
Main started
Coroutine started
Coroutine finished
Main finished

继续看一下执行过程:

  1. main 函数开始执行,打印出 Main started。
  2. 调用 coroutine 函数,将其作为一个协程对象运行。
  3. 在 coroutine 函数中,打印出 Coroutine started。
  4. 在 coroutine 函数中,使用 await asyncio.sleep(1) 暂停函数的执行,等待1秒钟。
  5. 在1秒钟后,恢复 coroutine 函数的执行,并打印出 Coroutine finished。
  6. main 函数恢复执行,打印出 Main finished。

在上面的代码中,使用 async 关键字定义了一个原生协程函数 coroutine,并在其中使用 await 关键字来暂停函数的执行,等待异步 I/O 操作的完成。通过这种方式,可以在原生协程中编写异步并发代码,从而提高代码的性能和效率。

两种协程对比

Python 3 中原生协程和生成器协程是两种不同的协程实现方式,它们各自有自己的特点和适用场景。下面,通过对比它们的区别和优缺点,才可以更好地理解它们之间的异同,以便选择适合自己的协程实现方式,从而更好地编写高效、可维护的异步程序。

  1. 区别:
  • 定义方式不同:原生协程使用 async/await 关键字来定义,而生成器协程使用 yield 关键字来定义。
  • 返回方式不同:原生协程使用 return 语句来返回结果,而生成器协程使用 yield 语句来返回结果。
  • 调用方式不同:原生协程使用 await 关键字来调用,而生成器协程使用 yield from 或 yield 语句来调用。
  • 内部实现不同:原生协程通过 asyncio 库来实现,而生成器协程是 Python 语言内置的特性。
  1. 优缺点:
  • 原生协程的优点:
    • 代码简洁易懂:使用 async/await 关键字,可以编写出更简洁易懂的协程代码。
    • 性能更高:原生协程不需要创建生成器对象,也不需要通过 yield 语句来控制函数的执行流程,因此能够更加高效地处理异步操作。
    • 支持异步 I/O 和任务处理:原生协程可以支持异步 I/O 操作和并发任务处理,可以在处理异步操作时更加灵活。
  • 原生协程的缺点:
    • 兼容性差:原生协程是 Python 3.5 版本之后才引入的新特性,因此在旧版本的 Python 中无法使用。
    • 异常处理不方便:原生协程在处理异常时比较麻烦,需要使用 try/except 语句来处理。
  • 生成器协程的优点:
    • 兼容性好:生成器协程是 Python 2 和 Python 3 都支持的特性。
    • 可读性好:生成器协程使用 yield 关键字来实现,代码逻辑清晰易懂。
    • 异常处理方便:生成器协程在处理异常时比较方便,可以使用 try/except 语句来处理。
  • 生成器协程的缺点:
    • 性能相对较低:生成器协程需要创建生成器对象,也需要通过 yield 语句来控制函数的执行流程,因此处理异步操作时性能相对较低。
    • 功能有限:生成器协程不能像原生协程一样支持异步 I/O 操作和任务处理。

实战案例

接下来,模拟一个场景,假设实现一个异步的批量处理任务的工具,使用原生协程来实现。

看下面代码:

import asyncio
import randomasync def batch_process_task(tasks, batch_size=10):# 将任务列表划分为多个批次for i in range(0, len(tasks), batch_size):batch = tasks[i:i+batch_size]# 使用原生协程来异步处理每个批次的任务await asyncio.gather(*[process_task(task) for task in batch])async def process_task(task):# 模拟任务处理过程await asyncio.sleep(random.uniform(0.5, 2.0))print("Task {} processed".format(task))async def main():# 构造任务列表tasks = [i for i in range(1, 101)]# 并发处理批量任务await batch_process_task(tasks, batch_size=10)if __name__ == '__main__':asyncio.run(main())

输出:

[root@workhost k8s]# python3 test.py 
Task 9 processed
Task 10 processed
Task 1 processed
Task 8 processed
Task 6 processed
Task 4 processed
Task 3 processed
Task 2 processed
Task 5 processed
...
...

batch_process_task函数使用原生协程来处理每个批次的任务,而process_task函数则是处理每个任务的函数。main函数则是构造任务列表,并且使用batch_process_task函数来异步地处理批量任务。

如果你对Python感兴趣,想要学习python,这里给大家分享一份Python全套学习资料,都是我自己学习时整理的,希望可以帮到你,一起加油!

😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓
Python全套学习资料

在这里插入图片描述

1️⃣零基础入门

① 学习路线

对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

② 路线对应学习视频

还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~
在这里插入图片描述

③练习题

每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!
在这里插入图片描述

2️⃣国内外Python书籍、文档

① 文档和书籍资料

在这里插入图片描述

3️⃣Python工具包+项目源码合集

①Python工具包

学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!
在这里插入图片描述

②Python实战案例

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

③Python小游戏源码

如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!
在这里插入图片描述

4️⃣Python面试题

我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
在这里插入图片描述
在这里插入图片描述

上述所有资料 ⚡️ ,朋友们如果有需要的,可以扫描下方👇👇👇二维码免费领取🆓
在这里插入图片描述

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

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

相关文章

APM固件编译和仿真

事情起因 主要想对无人机APM固件进行仿真的算法验证,因实际飞行的过程实际验证太浪费飞机了,所以就先试用仿真对算法进行仿真开发。 一,环境搭建 环境搭建我建议参考官方英文教程,英文教程写的比较全,不懂可以自己使…

智能 GPT 图书馆又重生了

智能 GPT 图书馆又重生了 作者:程序员小白条 1)概述 自从大二寒假准备开始筹备这个项目,到现在已经一年了,这个项目能维护一年,不愧是我.jpg。本来这个项目只是想练练手,因为那时候刚学完 Spring Boot2 V…

如何将门脸图片文字识别为excel表格数据?

对于市场调查人员而言,最烦的事莫过于对路边的小店进行逐一记录了,有没有效率高点的办法,不用人工录入呢?我来告诉你一个秘密:先将小店的牌子(门脸)拍下来,然后用OCR软件批量转成exc…

安卓自动化 APP:轻松关闭任意开屏广告 | 开源日报 No.116

gkd-kit/gkd Stars: 8.7k License: GPL-3.0 基于无障碍 高级选择器 订阅规则的自定义屏幕点击 APP,主要功能包括实现跳过任意开屏广告、关闭应用内部弹窗广告以及一些快捷操作,如微信电脑登录自动同意和领取红包等。其核心优势和特点包括:…

SpringBoot Whitelabel Error Page 报错--【已解决】

springboot 报错信息如下 这个报错页面就是个404 ,代表你访问的url 没有对应的的requestmapping 其实没啥影响的一个问题,但是看到Error 就是不爽,改了他丫的 解决方法如下 一、调整application.properties配置【治标不治本】 server.err…

JVM虚拟机运行时数据区程序计数器和元空间和线程控制块

阅读前提是对虚拟机有一定的理解 文章目录 阅读前提是对虚拟机有一定的理解16.堆、(方法区)元空间、虚拟机栈、程序计数器、本地方法栈16.1每个线程私有pc、vms、nms,共享 堆和堆外空间(元空间等) 1.虚拟机中运行时数据区中的方法区被元空间取代2. 用于存…

Jmeter自动判定运行结果(断言)

大家知道在jmeter中如果要查看运行结果可以通过添加监听器里面的查看结果树进行验证,但是这种方式查看结果依然是通过人眼进行比对的,为了能够解放双眼,可以通过jmeter自带的断言功能进行结果的自动判定,这样也算是进行一个简单的…

Apache Seatunnel本地源码构建编译运行调试

Apache Seatunnel本地源码构建编译运行调试 文章目录 1. 环境准备1.1 Java环境1.2 Maven1.3 IDEA1.4 Docker环境1.5 Mysql8.0.281.6 其它环境准备 2. 源码包下载3. idea项目配置3.1 项目导入3.2 maven配置3.3 项目JDK配置3.4 项目启动参数配置3.4.1 seatunnel项目启动参数配置3…

Qt之使用QListView加载相册(富文本ToolTip)

一.效果 二.实现 #include "mainwindow.h" #include "ui_mainwindow.h"#include <QStandardItemModel> #include <QFont>MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);QFont…

内衣洗衣机好用吗?专门洗内衣内裤的热门小型洗衣机

随着人们的生活水平的提升&#xff0c;越来越多小伙伴来开始追求更高的生活水平&#xff0c;一些智能化的小家电就被发明出来&#xff0c;而且内衣洗衣机是其中一个。现在通过内衣裤感染到细菌真的是越来越多&#xff0c;所以我们对内衣裤的清洗频次会高于普通衣服&#xff0c;…

【赠书活动】OpenCV4工业缺陷检测的六种方法

文章目录 前言机器视觉缺陷检测工业上常见缺陷检测方法延伸阅读推荐语 赠书活动 前言 随着工业制造的发展&#xff0c;对产品质量的要求越来越高。工业缺陷检测是确保产品质量的重要环节&#xff0c;而计算机视觉技术的应用能够有效提升工业缺陷检测的效率和精度。 OpenCV是一…

【数据结构】八大排序之简单选择排序算法

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 目录 一.简单选择排序简介及思路 二.简单选择排序的代码实现 三.简单选择排序的优化 四.简单选择排序的时间复杂度分析 结语 一.简单选择排序简介及思路 简单选择排序算法…

Koa.js 入门手册:洋葱模型插件机制详解以及常用中间件

前言 Nodejs 提供了 http 能力&#xff0c;我们通过如下代码可以快速创建一个http server服务 const http require(http);http.createServer((req, res) > {res.write(hello\n);res.end();}).listen(3000);使用nodejs提供的原生能力启动一个http server并不麻烦&#xff…

界面控件DevExpress WPF Dock组件,轻松创建类Visual Studio窗口界面!

本文主要为大家介绍DevExpress WPF控件中的Dock组件&#xff0c;它能帮助用户轻松创还能受Microsoft Visual Studio启发的Dock窗口界面。 P.S&#xff1a;DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress …

Python入门必看的关键字教程,清晰易懂

文章目录 前言FalseNoneTrueand,orasassertbreak与continueclassdefdelif,elif,elsetry,except,finally,raisefor,in,whileimport,fromglobalislambdanonlocalnotpassreturnwithyield、async 与 awaitPython技术资源分享1、Python所有方向的学习路线2、学习软件3、入门学习视频…

每天五分钟计算机视觉:谷歌的Inception模块的计算成本的问题

计算成本 Inception 层还有一个问题,就是计算成本的问题,我们来看一下55 过滤器在该模块中的计算成本。 原始图片为28*28*192经过32个5*5的过滤操作,它的计算成本为: 我们输出28*28*32个数字,对于输出的每个数字来说,你都需要执行 55192 (5*5为卷积核的大小,192为通道…

如何通过EventChannel实现Flutter与原生平台之间的双向通信

本文将介绍如何通过EventChannel实现Flutter与原生平台之间的双向通信。如果想了解如何通过MethodChannel实现Flutter调用Android原生平台的方法,可以参考上篇文章。 Flutter如何实现与Android底层平台通信,调用底层Android原生方法https://sgknight.blog.csdn.net/article/…

威雅学校快讯:携手未来,同梦而行,威雅学校喜迎英国姐妹校管理团队访校视察

威雅学校喜迎英国姐妹校访校团 Visit from our sister school in the UK 英国威科姆阿贝学校 威雅学校大家庭 WAS Family 常州威雅WASCZ 香港威雅WASHK 杭州威雅WASHZ 南京威雅WASNJ 向春而行&#xff0c;卓越可期。日前&#xff0c;四所威雅学校均先后迎来了英国姐妹学校W…

人工智能辅助下的人工心脏:未来医疗的奇迹

导言 人工智能在医学领域的应用不断创新&#xff0c;其中人工心脏作为医疗工程的重要方向&#xff0c;将为心血管疾病患者带来新的治疗可能性。本文将深入研究人工智能辅助下的人工心脏技术&#xff0c;其原理、应用以及对未来医疗的影响&#xff0c;探讨人工心脏的发展历程、面…

vue看板使用电子数字

1、下载字体 https://www.dafont.com/theme.php?cat302&text0123456789 2、下载后将压缩包解压,并上传到https://link.csdn.net/?targethttps%3A%2F%2Fwww.fontsquirrel.com%2Ftools%2Fwebfont-generator 然后下载 3、项目中使用 在Vue项目中的assets中新建fonts文件夹…