使用yield和send实现协程

协程的本质是在一个线程里实现多个任务之间的来回切换,我们使用yield和send可以实现简单的协程

 def pro():
print(1)
n = yield "a"
print(n)
yield "b" def con():
g = pro()
a = next(g)
print(a)
b = g.send(2)
print(b) con()

首先我们来分析一下,我们定义了两个函数:pro是生产者,con是消费者,利用yield和send可以在两个函数之间切换,send是将值传给上一个yield,然后执行pro函数的代码直到下一个yield时,又会

返回到con函数,这样就实现了两个任务之间的来回切换,具体分析间如下代码:

 # def pro():    # ----第3步
# print(1) # 打印1-----第5步
# n = yield "a" # 执行等号右边的语句,把"a"的值传给next(g)这个整体(之后跳转到con函数)----第6步 # 把2的值赋给变量n---第10步
# print(n) # 打印n---第11步
# yield "b" # 执行yield "b"语句---第12步
#
#
# def con():
# g = pro() # 获取生成器-----第2步
# a = next(g) # 执行等号右边的语句(之后会跳转到pro函数)---第4步 # 把"a"是值赋给变量a-----第7步
# print(a) # 打印a----第8步
# b = g.send(2) # 执行等号右边的语句,把2发送给上一个yield----第9步 # 把"b"的值赋给变量b----第13步
# print(b) # 打印b----第14步
#
#
# con() # 执行con函数-----第1步

注意:

(1)yield、next和send左边有等号时(第3、10、12行)等号两边的语句是分开执行的,并不是yield一个值后马上把值赋给左边的变量,而是执行生成器函数,直到遇到下一个yield,再将yield的值传给这个变量

(2)yield切换也会花时间的,所以如果任务没有I/O。那么在两个任务之间切换反而会降低效率,因为每一次切换都要记录状态,在切换回来之后还要读取状态

(3)yield只能做到状态保存和状态切换,不能遇到I/O自动切换

(4)只有遇到I/O时能够自动切换,并且I/O阻塞的时间可以和执行任务代码共享这段时间,那么才真正的提高了程序的执行效率

使用yield和send实现简单的协程函数的更多相关文章

  1. python基础----迭代器、生成器、协程函数及应用(面向过程实例)

    一.什么是迭代器协议 1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个StopIteration异常,以终止迭代 (只能往后走不能往前退) 2.可迭代 ...

  2. Python基础(协程函数、内置函数、递归、模块和包)-day05

    写在前面 上课第五天,打卡: 凭着爱,再回首: 一.协程函数(生成器:yield的表达式形式) 1.yield 的语句形式: yield 1 - 这种方式在 Python基础(函数部分)-day04  ...

  3. python协程函数、递归、匿名函数与内置函数使用、模块与包

    目录: 协程函数(yield生成器用法二) 面向过程编程 递归 匿名函数与内置函数的使用 模块 包 常用标准模块之re(正则表达式) 一.协程函数(yield生成器用法二) 1.生成器的语句形式 a. ...

  4. python协程函数应用 列表生成式 生成器表达式

    协程函数应用 列表生成式 生成器表达式   一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._n ...

  5. Py修行路 python基础 (十二) 协程函数应用 列表生成式 生成器表达式

    一.知识点整理: 1.可迭代的:对象下有_iter_方法的都是可迭代的对象 迭代器:对象._iter_()得到的结果就是迭代器 迭代器的特性: 迭代器._next_() 取下一个值 优点: 1.提供了 ...

  6. python之协程函数、递归、二分法

    一.协程函数: 协程函数的语法: def eater(name): print('%s说:我开动啦' %name) food_list=[] while True: food=yield food_l ...

  7. python基础之协程函数、列表表达式、生成器表达式

    一.协程函数 协程函数的定义?如果在一个函数内部yield的使用方式是表达式形式的话,如x=yield,那么该函数称为协程函数 协程函数补充: def init(func): def wrapper( ...

  8. python自动化 协程函数、二分查找、模块搜索

    协程函数 yiled: 把函数的执行结果封装好__iter__和__next__得到一个迭代器 与return功能类似,都可以返回值,但是return只能返回一次只 def fun(count): p ...

  9. python 列表表达式、生成器表达式和协程函数

    列表表达式.生成器表达式和协程函数 一.列表表达式: 常规方式示例: egg_list=[] for i in range(100): egg_list.append("egg%s" ...

随机推荐

  1. Markdown 使用技巧

    懒得复制,直接贴网页吧 懒得复制,直接贴网页吧*2 懒得复制,直接贴网页吧*3

  2. 使用 sizeof 获取字符串数组的大小

    @2018-11-1 字符串组成的数组存放于指针数组中,使用 sizeof 获取数组大小 [验证] #include <stdio.h> #define BootScreen " ...

  3. luogu3278/bzoj3323 多项式的运算 (splay)

    mulx的操作,其实就是给r+1的系数+=r的系数,然后删掉r,把l~r-1向右移一位,再插一个0到原来的位置 splay维护区间加和区间乘就好了 (一定要注意做事的顺序,一件事都做完了再去做别的,否 ...

  4. 【算法】php实现斐波那契数列

    斐波那契数列指的是这样一个数列 1, 1, 2, 3, 5, 8, 13, 21.这个数列从第3项开始,每一项都等于前两项之和. 根据这个定义,斐波那契数列的递推公式是:f(n)=f(n-1)+f(n ...

  5. Nginx简易编译安装

    1.下载Nginx: http://nginx.org/download/nginx-1.6.3.tar.gz 2.安装Pcre.Zlib.Openssl等相关组件: [root@track ngin ...

  6. Kafka学习之路

    一直在思考写一些什么东西作为2017年开篇博客.突然看到一篇<Kafka学习之路>的博文,觉得十分应景,于是决定搬来这“他山之石”.虽然对于Kafka博客我一向坚持原创,不过这篇来自Con ...

  7. [luogu1486][郁闷的出纳员]

    题目链接 思路 这个题其实就是对于treap中的删除操作进行一些修改.自己yy了一种做法.就是在删除的时候,如果要删除的数比这棵子树的根大,那么就把根变成根的右孩子,这样就相当于删除了整棵左子树和根节 ...

  8. bzoj1791[IOI2008]Island岛屿(基环树+DP)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1791 题目大意:给你一棵n条边的基环树森林,要你求出所有基环树/树的直径之和.n< ...

  9. [NOI2017]游戏(2-SAT)

    这是约半年前写的题解了,就搬过来吧 感觉这是NOI2017最水的一题(当然我还是不会2333),因为是一道裸的2-SAT.我就是看着这道题学的2-SAT 算法一:暴力枚举.对于abc二进制枚举,对于x ...

  10. Codeforces Round #525 (Div. 2)

    Codeforces Round #525 (Div. 2) 哎,忍不住想吐槽一下,又要准备训练,又要做些无聊的事,弄得我都想退出了. 好好的训练不好么???? 只能做出两道水题,其实C题,感觉做出来 ...