热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python高级编程技巧协程

先来说几个概念同步:代码调用IO操作时,必须等到操作完成返回的调用方式,同步是并行异步:代码调用IO操作时,必

先来说几个概念
同步: 代码调用IO操作时,必须等到操作完成返回的调用方式,同步是并行
异步: 代码调用IO操作时,必须等到操作完成返回的调用方式,异步是串行
阻塞: 从调用者的角度说,如果调用时被卡住,不再往下执行,需要等待就是说阻塞
非阻塞: 从调用者的角度说,如果调用时没有被卡住,继续往下执行无需等待就是说非阻塞


生成器—send方法


  1. 启动生成器
  2. 发送值给生成器返回

def generator(num):a, b &#61; 0, 1con &#61; 0while con < num:result &#61; yield a # 先执行右边&#xff0c;会阻塞在这里print(&#39;result>>&#39;, result)a, b &#61; b, a &#43; bcon &#43;&#61; 1return 123g &#61; generator(5)
g.close() # 关闭生成器&#xff0c;后续的值将取不了
# send 方法可以启动生成器都是第一次传的值必须是空
print(next(g)) # 这也可以取出来
print(g.send(&#39;huran&#39;))for i in g: # 还可以用for循环print(i, end&#61;&#39;-&#39;)
# 捕获生成器的返回值
while True:try:ret &#61; next(g)print(ret)except Exception as e:print(e.value)break

在这里插入图片描述


yield完成多任务

利用就是yield会阻塞的特性

import timedef task1():while True:print("--1--")time.sleep(0.1)yielddef task2():while True:print("--2--")time.sleep(0.1)yielddef main():t1 &#61; task1()t2 &#61; task2()while True:next(t1)next(t2)if __name__ &#61;&#61; "__main__":main()

yield from

chain&#xff08;&#xff09;可传入多个可迭代的对象&#xff0c;对他们进行一个for循环取出值来。

lis &#61; [1, 2, 3]
dis &#61; {&#39;name&#39;: &#39;juran&#39;,&#39;age&#39;: 18
}def my_chian(*args, **kwargs):for val in args:yield from valfor value in my_chian(lis, dis):print(value)

yield from

def generator_1(): # 子生成器total &#61; 0while True:x &#61; yieldprint(&#39;加&#39;, x)if not x: breaktotal &#43;&#61; xreturn totaldef generator_2(): # 委托生成器while True:total &#61; yield from generator_1() # 子生成器print(&#39;加和总数是:&#39;, total)def main(): # 调用方# g1 &#61; generator_1()# g1.send(None)# g1.send(2)# g1.send(3)# g1.send(None)g2 &#61; generator_2()g2.send(None)g2.send(2)g2.send(3)g2.send(None)if __name__ &#61;&#61; &#39;__main__&#39;:main()

【子生成器】&#xff1a;yield from后的generator_1()生成器函数是子生成器
【委托生成器】&#xff1a;generator_2()是程序中的委托生成器&#xff0c;它负责委托子生成器完成具体任务。
【调用方】&#xff1a;main()是程序中的调用方&#xff0c;负责调用委托生成器。


协程

协程&#xff0c;又称微线程
协程是python个中另外一种实现多任务的方式&#xff0c;只不过比线程更小占用更小执行单元&#xff08;理解为需要的资源&#xff09;
Python中的协程大概经历了如下三个阶段&#xff1a;


  1. 最初的生成器变形yield/send
  2. yield from
  3. 在最近的Python3.5版本中引入async/await关键字

协程的实现

from greenlet import greenlet
import timedef greenlet_1():while True:print(&#39;--1--&#39;)g2.switch()time.sleep(0.5)def greenlet_2():while True:print(&#39;--2--&#39;)g1.switch()time.sleep(0.5)g1 &#61; greenlet(greenlet_1)
g2 &#61; greenlet(greenlet_2)
g1.switch()

gevent实现多任务
遇到等待会自动切换到另外一个任务

import gevent
from gevent import monkey
monkey.patch_all() # 将所用的噩耗时操作换为gevent模块的def test1(n):for i in range(n):print(gevent.getcurrent(), i)gevent.sleep(0.5) # 这里会有等待&#xff0c;会自动在上一步自动切换到另外一个def test2():while True:print(gevent.getcurrent(), &#39;---2---&#39;)gevent.sleep(0.5) # 这里会有等待&#xff0c;会自动在上一步自动切换到另外一个t1 &#61; gevent.spawn(test1, 2) # 第一个参数是对象&#xff0c;第二个是参数&#xff08;传入函数中的&#xff0c;可有可无&#xff09;
t2 &#61; gevent.spawn(test2)
t1.join() # 要等到执行完毕&#xff0c;否则直接到这里
t2.join()

案例&#xff1a;

import gevent
from gevent import monkey
monkey.patch_all()
import requestsdef download(url):print("get:%s" % url)ret &#61; requests.get(url)data &#61; ret.textprint(len(data), ret)g1 &#61; gevent.spawn(download, &#39;https://www.kancloud.cn/ju7ran/gaoji/1474878&#39;)
g2 &#61; gevent.spawn(download, &#39;https://fanyi.baidu.com/?fr&#61;websearch_submit&pid&#61;sogou__free#pt/zh/%3CGreenlet&#39;)
g1.join()
g2.join()
访问的网站并不是按照你写的顺序来执行完成的&#xff0c;而是先执行完时间短一点的&#xff0c;

总结&#xff1a;
进程是资源分配的基本单位
线程是操作系统调度和执行的单位
进程切换需要的资源很最大&#xff0c;效率很低
线程切换需要的资源一般&#xff0c;效率一般&#xff08;当然了在不考虑GIL的情况下&#xff09;
协程切换任务资源很小&#xff0c;效率高
多进程、多线程根据cpu核数不一样可能是并行的&#xff0c;但是协程是在一个线程中 所以是并发


推荐阅读
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • 这篇文章主要介绍了Python拼接字符串的七种方式,包括使用%、format()、join()、f-string等方法。每种方法都有其特点和限制,通过本文的介绍可以帮助读者更好地理解和运用字符串拼接的技巧。 ... [详细]
  • 本文由编程笔记#小编为大家整理,主要介绍了logistic回归(线性和非线性)相关的知识,包括线性logistic回归的代码和数据集的分布情况。希望对你有一定的参考价值。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 使用Ubuntu中的Python获取浏览器历史记录原文: ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • 本文介绍了在处理不规则数据时如何使用Python自动提取文本中的时间日期,包括使用dateutil.parser模块统一日期字符串格式和使用datefinder模块提取日期。同时,还介绍了一段使用正则表达式的代码,可以支持中文日期和一些特殊的时间识别,例如'2012年12月12日'、'3小时前'、'在2012/12/13哈哈'等。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 超级简单加解密工具的方案和功能
    本文介绍了一个超级简单的加解密工具的方案和功能。该工具可以读取文件头,并根据特定长度进行加密,加密后将加密部分写入源文件。同时,该工具也支持解密操作。加密和解密过程是可逆的。本文还提到了一些相关的功能和使用方法,并给出了Python代码示例。 ... [详细]
  • java drools5_Java Drools5.1 规则流基础【示例】(中)
    五、规则文件及规则流EduInfoRule.drl:packagemyrules;importsample.Employ;ruleBachelorruleflow-group ... [详细]
author-avatar
手机用户2602920093
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有