实例详解python生成器协程运算


本文摘自php中文网,作者巴扎黑,侵删。

下面小编就为大家带来一篇python 生成器协程运算实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

一、yield运行方式

我们定义一个如下的生成器:


1

2

3

4

5

6

7

8

9

10

11

12

def put_on(name):

 print("Hi {}, 货物来了,准备搬到仓库!".format(name))

 while True:

  goods = yield

  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))

  

p = put_on("bigberg")

  

#输出

G:\python\install\python.exe G:/python/untitled/study4/test/double.py

  

Process finished with exit code 0

当我们把一个函数通过yield转换成生成器,直接运行函数是不会出现结果返回的。因为此时函数已经是个生成器了,我们要通过next()来取得值,并且在遇到yield时再次跳出函数。


1

2

3

4

print(type(p))

  

#输出

<class 'generator'>

我们添加next()方法:


1

2

3

4

5

6

7

8

9

10

11

def put_on(name):

 print("Hi {}, 货物来了,准备搬到仓库!".format(name))

 while True:

  goods = yield  #遇到yield中断

  print("货物[%s]已经被%s搬进仓库了。"%(goods,name)) #中断后运行部分

  

p = put_on("bigberg")

p.__next__()

  

#输出

Hi bigberg, 货物来了,准备搬到仓库!

此时函数中断在 goods = yield 的地方,当我们再次调用next()函数时,函数只会运行中断以后的内容,即上例中的yield下面部分。

我们再添加一个next():


1

2

3

4

5

6

7

8

9

10

11

12

13

def put_on(name):

 print("Hi {}, 货物来了,准备搬到仓库!".format(name))

 while True:

  goods = yield

  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))

  

p = put_on("bigberg")

p.__next__()

p.__next__()

  

#输出

Hi bigberg, 货物来了,准备搬到仓库!

货物[None]已经被bigberg搬进仓库了。

我们可以第二次next()运行的是yield下面的部分内容,但是并没有给goods传值,所以货物是 None。

小结:

通过yield将函数转换为生成器,需要使用next()方法才能运行

yield只是保留函数的中断状态,再次调用next()会执行yield后面的部分

yield如果没有返回值,会返回一个None空值

二、send()传值


1

2

3

4

5

6

7

8

9

10

11

12

13

def put_on(name):

 print("Hi {}, 货物来了,准备搬到仓库!".format(name))

 while True:

  goods = yield

  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))

  

p = put_on("bigberg")

p.__next__()

p.send("瓜子")

  

#输出

Hi bigberg, 货物来了,准备搬到仓库!

货物[瓜子]已经被bigberg搬进仓库了。

小结:

__next__()只是调用这个yield,也可以说成是唤醒yield,但是不不会给yield传值。

send()方法调用yield是,能给yield传值

使用send()函数之前必须使用__next__(),因为先要中断,当第二次调用时,才可传值。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

def put_on(name):

 print("Hi {}, 货物来了,准备搬到仓库!".format(name))

 while True:

  goods = yield

  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))

  

p = put_on("bigberg")

p.__next__()

p.send("瓜子")

p.send("花生")

p.send("饼干")

p.send("牛奶")

  

#多次调用send()

Hi bigberg, 货物来了,准备搬到仓库!

货物[瓜子]已经被bigberg搬进仓库了。

货物[花生]已经被bigberg搬进仓库了。

货物[饼干]已经被bigberg搬进仓库了。

货物[牛奶]已经被bigberg搬进仓库了。

三、单线程实现并行效果(协程)


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

import time

  

  

def put_on(name):

 print("Hi {}, 货物来了,准备搬到仓库!".format(name))

 while True:

  goods = yield

  print("货物[%s]已经被%s搬进仓库了。"%(goods,name))

  

  

def transfer(name):

 p = put_on('A')

 p2 = put_on('B')

 p.__next__()

 p2.__next__()

 print("%s将货物送来了!"%name)

 for i in range(5):

  time.sleep(1)

  print("%s递过来两件货物"%name)

  p.send("瓜子")

  p2.send("花生")

  

transfer("bigberg")

  

#输出

Hi A, 货物来了,准备搬到仓库!

Hi B, 货物来了,准备搬到仓库!

bigberg将货物送来了!

bigberg递过来两件货物

货物[瓜子]已经被A搬进仓库了。

货物[花生]已经被B搬进仓库了。

bigberg递过来两件货物

货物[瓜子]已经被A搬进仓库了。

货物[花生]已经被B搬进仓库了。

bigberg递过来两件货物

货物[瓜子]已经被A搬进仓库了。

货物[花生]已经被B搬进仓库了。

bigberg递过来两件货物

货物[瓜子]已经被A搬进仓库了。

货物[花生]已经被B搬进仓库了。

bigberg递过来两件货物

货物[瓜子]已经被A搬进仓库了。

货物[花生]已经被B搬进仓库了。

以上就是实例详解python生成器协程运算的详细内容,更多文章请关注木庄网络博客!!

相关阅读 >>

Python2和3哪个更常用

Python操作sql server数据库的方法

Python操作mysql的实例详解

Python能开发exe软件吗

Python的爬虫是什么意思

Python中有for函数吗

Python中的装饰器是什么?装饰器是如何工作的?

Python中缩进是什么

Python未来会进课本么

什么是 Python

更多相关阅读请进入《Python》频道 >>




打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,您说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

分享从这里开始,精彩与您同在

评论

管理员已关闭评论功能...