python协程笔记

一、协程

  协程 是为非抢占式多任务产生子程序的计算机程序组件,协程允许不同入口点在不同位置暂停或开始执行程序

  可以看做一个可以暂停的函数以及一个生成器

二、协程常用包

  asyncio,tornado,gevent

三、协程的实现

  yield返回

  send调用

四、协程的四种状态

  inspect.getgeneratorstate(...)函数确认,该函数会返回下面字符中的一:

    GEN_CREATER:等待开始执行

    GEN_RUNNING:解释器正在执行

    GEN_SUSPENED:在yield表达式处暂停

    GEN_CLOSED:执行结束

  next预激(prime)

  案例1

 1 def My_Coroutines():
 2     print('-->start')
 3     x = yield
 4     print('x is %s' % x)
 5     print('-->end')
 6 
 7 g = My_Coroutines()
 8 next(g)
 9 
10 g.send('Q')
-->start
x is Q
-->end
---------------------------------------------------------------------------
StopIteration                             Traceback (most recent call last)
<ipython-input-1-dfd01338da14> in <module>()
      8 next(g)
      9 
---> 10 g.send('Q')

StopIteration:
out1

预激:

next(t) 或者 t.seed(None)

该程序会在程序结束后抛出StopIteration异常,因为在send将信号Q发送到原函数执行完毕后,在函数中找不到下一个yield,又返回到send抛出异常,解决方案可以在结尾加上yield

  案例2

 1 def My_Coroutines():
 2     print('-->start')
 3     x = yield
 4     print('x is %s' % x)
 5     print('-->end')
 6     yield
 7 
 8 g = My_Coroutines()
 9 next(g)
10 g.send('Q')
-->start
x is Q
-->end
out2

协程执行的顺序是:

  预激函数(next(g)) --> print('-->start') --> 在yield表达式处暂停 -->预激执行结束 --> 再次调用原函数(g.send('Q')) --> 'Q'传入x --> print('x is %s' % x) --> print('-->end') --> 在yield表达式处暂停 -->程序结束

  案例3

 1 def My_Coroutines(a):
 2     print('-->start')
 3     print('a is {0}'.format(a))
 4     b = yield a
 5     print('a b is {0} {1}'.format(a,b))
 6     c = yield a + b
 7     print('a b c is {0} {1} {2}'.format(a,b,c))
 8     yield a + b + c
 9     
10 a = My_Coroutines(5)
11 
12 q1 = next(a)
13 print(q1)
14 q2 = a.send(3)
15 print(q2)
16 q3 = a.send(1)
17 print(q3)
-->start
a is 5
5
a b is 5 3
8
a b c is 5 3 1
9
out3

五、yield from

  http://flupy.org/resources/yield-from.pdf

  1.yield from

    为了让生成器,能简易的在其他函数中直接调用,就产生了yield from

    yield from 就是从其他函数中找到子生成器中的yield

    yield from从内部捕获StopIteration异常

六、委派生成器

  包含yield from <iterable> 表达式的生成器函数

    案例4

 出自:https://blog.csdn.net/chenbin520/article/details/78111399?locationNum=7&fps=1 

 1 def htest():
 2     i = 1
 3     while i < 4:
 4         n = yield i
 5         if i == 3:
 6             return 100
 7         i += 1
 8 
 9 #委派生成器
10 def itest():
11     val = yield  from htest()
12     print(val)
13 
14 t = itest()
15 t.send(None)
16 j = 0
17 while j < 3:
18     j += 1
19     try:
20         t.send(j)
21     except StopIteration as e:
22         print('异常了')

通过

把yield from换成yield

把return换成yield

之类的更改,能够窥到yield from的一思半解

七、asyncio异步

   参阅:http://python.jobbole.com/87310/

posted @ 2018-08-31 10:51  AdriftCore  阅读(176)  评论(0编辑  收藏  举报