python中协程与函数的区别_python协程 yield和yield_from的区别

面试被问到python3 的asyncio模块、python2中的yield和yield from的区别

面的第一家觉得回答的不是很好, 回来进行收集整理一番,以便巩固记忆

Python中的协程大概经历了三个阶段:

最初的生成器变形yield/send

引入@asyncio.coroutine和yield from

在最近的python3.5版本中引入async/await字段

下面将对上边的三个阶段进行说明

1、 生成器变形yield/send

普通函数中如果出现了yield, name该函数就不是普通的函数, 而是一个生成器

1 def gen():2 for i in range(1,10):3 yieldi4

5 g =gen()6 for i ing:7 print(i)

像上面的代码 g 就是一个生成器, 生成器就是一种迭代器,可以使用for进行迭代,生成器最大的特点就是可以接受一个外部传入的变量,根据变脸内容计算返回结果

1 def gen():2 whileTrue:3 i = 0

4 x = yieldi5 if x == 0:6 break

7 i = i*x8 g =gen()9 print(g.send(None))10 print(g.send(1))11 print(g.send(2))12 print(g.send(0))

上面的步骤中,x = yield i最重要也最容易理解错,下面详细接介绍该语句的运行流程

其实x = yield i包含了三个步骤:

向函数外抛出(返回)i

暂停,等待next()和send()恢复

赋值receive=MockGetValue() 。 这个MockGetValue()是假想函数,用来接收send()发送进来的值

执行流程:

通过g.send(None)或者next(g)启动生成器函数, 并执行到第一个yield语句停止,注意在这里相当于执行了上边的1,2步,程序返回yield后边的i值后暂停,并没有执行第三步, 注意第一次这里send(None)函数的参数必须传None否者会报错

通过g.send(1), 会传入值,从上一次暂停的位置继续执行,从第三步执行赋值操作后 再执行1,2步。

当我们传g.send(0)时候, 会主动break 并且退出循环,最后整个函数执行完毕,所以会得到StopIteration异常。

2、yield from

1 def g1():2 yield range(5)3 def g2():4 yield from range(5)5

6 it1 =g1()7 it2 =g2()8 for x init1:9 print(x)10

11 for x init2:12 print(x)13

14 """15 会输出16 range(0, 5)17 0

18 1

19 2

20 3

21 4

22 """

个人理解yield仅仅是截断并返回,而yield from相当于解析了后边的可迭代对象,并返回每一个item。

yield from iterable本质上等于for item in iterable: yield item的缩写版

注意:yield_from 后边的必须为可迭代对象(iterable)

3、 asyncio.cotoutine和yield from

yield from在asyncio模块中得以发扬光大。之前都是我们手工切换协程,现在当声明函数为协程后,我们通过事件循环来调度协程。

示例代码

1 importasyncio,random2 @asyncio.coroutine3 defsmart_fib(n):4 index =05 a =06 b = 1

7 while index

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值