Generator(生成器),入门初基,Coroutine(原生协程),登峰造极,Python3.10并发异步编程async底层实现

Generator(生成器),入门初基,Coroutine(原生协程),登峰造极,Python3.10并发异步编程async底层实现

普遍意义上讲,生成器是一种特殊的迭代器,它可以在执行过程中暂停并在恢复执行时保留它的状态。而协程,则可以让一个函数在执行过程中暂停并在恢复执行时保留它的状态,在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/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/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")

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

if __name__ == '__main__':  conn = Connection("v3u")  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  
X: 50.0, Y: 100.0 sent to v3u  
X: 33.333333333333336, Y: 66.66666666666667 sent to v3u  
X: 25.0, Y: 50.0 sent to v3u  
X: 20.0, Y: 40.0 sent to v3u  
链接丢失,进行回调  
X: 100.0, Y: 200.0 sent to 重新连接v3u  
X: 50.0, Y: 100.0 sent to 重新连接v3u  
X: 33.333333333333336, Y: 66.66666666666667 sent to 重新连接v3u  
X: 25.0, Y: 50.0 sent to 重新连接v3u  
X: 20.0, Y: 40.0 sent to 重新连接v3u

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

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

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

您猜怎么着?

<class 'coroutine'>

结语

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

发布者:admin,转转请注明出处:http://www.yc00.com/news/1693664347a729055.html

相关推荐

  • SparseTSF:用 1000 个参数进行长序列预测建模

    论文标题:SparseTSF: Modeling Long-term Time Series Forecasting with 1k Parameters论文链接:.00946代码链接::本文要介绍的SparseTSF,是一个极其轻量化的长

    2小时前
    00
  • ArcPy导出遥感影像属性表的方法

      本文介绍基于Python中的ArcPy模块,批量导出多个栅格数据的属性表,并将结果保存为Excel表格的方法。  首先,我们来明确一下本文的需求。现在在一个文件夹内,有多个.tif格式的栅格数据。其中,每一个栅格数据都有一张属性表,如下

    2小时前
    00
  • 独家推荐!这款端到端AI测试工具 Testim,让效率飙升!(支持移动端、Web端)

    大家好,我是狂师。在当今快速发展的软件开发时代,确保软件质量成为每个开发团队的首要任务。随着人工智能(AI)和机器学习(ML)技术的飞速发展,AI测试工具应运而生,为软件测试领域带来了革命性的变化。今天,我要向大家强烈推荐一款专为端到端测试

    2小时前
    00
  • AI 应用冷启动困境破解:小样本学习在垂直领域的迁移适配实战

    救命!AI 冷启动难题,被小样本学习 “拿捏” 了!家人们,在 AI 应用的世界里,冷启动堪称 “头号难题”。就好比你开了一家超有格调的新店,却无人问津,AI 模型就算潜力无限,没有足够数据 “投喂”,也只能 “巧妇难为无米之炊”。不过别慌

    2小时前
    00
  • 如何计算群体中的单倍型频率

    大家好,我是邓飞。昨天写了一篇(单倍型的显著性分析)的博文,里面介绍了为什么GWAS分析后,要进行单倍型的显著性分析,简而言之,如果显著性位点在block中,以block为代表进行利用,可以进行PRS(多基因评分)或者MAS(分子标记辅助选

    2小时前
    00
  • 相比于DeepSeek,Manus有哪些优势

    距离Manus出现快一个月了,最近关于Manus的文章网上很多,我也看了不少,但总感觉这些文章的内容写的有点偏颇。要么就是制造焦虑,要么就是大吹特吹Manus有多厉害。反正现在Manus名额开放的也不多,很多人还是云里雾里。这篇文章我会根据

    1小时前
    00
  • CUT&amp;Tag 数据处理和分析教程(5)

    引言本系列[1] 将开展全新的CUT&Tag 数据处理和分析专栏。重复去除CUT&Tag 技术会将接头序列插入到抗体连接的 pA-Tn5 附近的 DNA 中,而插入的具体位置会受到周围 DNA 可及性的影响。因此,那些起始和

    1小时前
    00
  • 设计模式:适配器模式(Adapter)(2)

    场景二:系统维护终于,你的系统交付完成,进入维保阶段。当你每天喜滋滋的挣着边际收益时,突然有一天,甲方爸爸又说:“某某供应商好像说改了什么接口,具体我也听不懂,你处理一下。”当你和对方联系时,可能瞬间气血攻心......什么?改接口了?不准

    1小时前
    00
  • 告别无效阅读!用ChatGPT一天狂读100篇文献

    还在为文献太多、读不完发愁?利用好ChatGPT,效率直接拉满!面对堆积如山的文献,只用ChatGPT“总结一下”简直是浪费算力。想让你的ChatGPT火力全开,精准提取文献重点!?关键就在Prompt!通过优化后的Prompt不仅省时省力

    1小时前
    00
  • 做跟随式的科研有意义吗?(原文来自于章冰(美国贝勒医学院))

    在朋友圈看到了章冰教授(美国贝勒医学院)点评生物信息学科研领域的跟随研究(或称为“Me-Too”研究)现象,非常有启发意义,借花献佛分享给大家!跟随研究(或称为“Me-Too”研究)通常指的是在已有研究基础上进行的模仿或扩展工作。这类研究在

    1小时前
    00
  • 一个成年小鼠大脑的scATAC

    前面在写ATACseq学习笔记的时候,后台有很多粉丝询问scATAC-seq有没有相关资料,现在就来学习,开个新专辑《scATAC-seq分析》~scATAC-seq用的最多的包就是Signac包了,这个包来自Seurat包的扩展,分析步骤

    1小时前
    00
  • 聊聊Spring AI的EmbeddingModel

    序本文主要研究一下Spring AI的EmbeddingModelEmbeddingModelspring-ai-coresrcmainjavaorgspringframeworkaiembeddingEmbeddingMo

    1小时前
    00
  • scMMO

    Basic Information 英文标题:scMMO-atlas: a single cell multimodal omics atlas and portal for exploring fine cell heterogeneit

    1小时前
    00
  • CAN总线如何区分和识别帧类型

    CAN总线是一种鲁棒的通信协议,广泛应用于汽车和工业领域,用于不同电子设备之间的可靠数据传输。理解 CAN 总线通信中的不同帧类型对于诊断、调试和确保系统高效运行至关重要。CAN 总线定义了四种主要帧类型:数据帧:携带从一个或多个发送器到接

    1小时前
    00
  • 优雅草星云物联网AI智控系统测试版本Beta测试版v1.0.1版本发布

    优雅草星云物联网AI智控系统测试版本Beta测试版v1.0.1版本发布-更新多项内容-PC版本vue端已经完成初步数据对接-鸿蒙原生端静态页面已完成90%-优雅草卓伊凡产品介绍成都星云智控科技有限公司,作为成都市一颗优雅草科技有限公司旗下子

    58分钟前
    00
  • Go 语言常见错误——标准库

    Go 语言的标准库就像一把瑞士军刀,功能强大,覆盖了从网络编程到文件操作等方方面面。然而,即便是再好的工具,使用不当也可能“翻车”。许多开发者在使用标准库时,常常踩进一些看似不起眼的坑,比如误解 API 的用法、忽略资源的正确释放,或者在并

    45分钟前
    20
  • Fabric8 Kubernetes 教程——Metrics、Resource

    Kubernetes 客户端提供了丰富的 API 来管理和操作 Kubernetes 集群中的资源。以下是一些常见的操作示例,涵盖了指标获取、资源管理、自定义资源定义(CRD)以及类型化和无类型资源 API 的使用。获取 MetricsKu

    43分钟前
    00
  • MediatR: .NET 平台上的命令查询职责分离 (CQRS) 库

    简介MediatR 是一个轻量级的库,用于实现应用程序中的中介者模式【实现命令查询职责分离 (CQRS) 模式和面向消息的架构】。通过将请求(命令或查询)与处理程序解耦,简化了应用程序的逻辑分层和扩展。主要特性• 命令和查询模式:支持命令和

    7分钟前
    00
  • 在 Centos7 上部署 ASP.NET 8.0 + YOLOv11 的踩坑实录

    本文将详细记录我在CentOS 7上部署ASP.NET 8.0结合YOLOv11目标检测项目过程中遇到的问题及解决方案,旨在为有类似需求的开发者提供参考。1. 背景随着人工智能技术的迅猛发展,目标检测成为了众多应用场景中的核心技术之一。YO

    3分钟前
    00
  • 一文掌握DeepSeek本地部署+Page Assist浏览器插件+C#接口调用+局域网访问!全攻略来了!

    大家好,我是编程乐趣。DeepSeek大火,网络上也看到很多人分享本地部署心得。但想要更细了解,还是要自己本地部署一次。我这次部署目标,就是在局域网服务器部署,并让局域网其他电脑可以直接访问。选择方案也是当前非常流行的:Ollma+Page

    1分钟前
    00

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信