协程的概念级描述(与线程对比):转自知乎 链接

  线程有两个必须要处理的问题:一是碰着阻塞式I\O会导致整个进程被挂起;

                二是由于缺乏时钟阻塞,进程需要自己拥有调度线程的能力。

  如果一种实现使得每个线程需要自己通过调用某个方法,主动交出控制权。那么我们就称这种线程是协作式的,即是协程。

在Python中关于协程的实现方式有三种:

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

以下代码均在Centos 7 Python3.6调试通过!

简单的yield使用描述:

def fun():
index = 0
while True:
yield index
index += 1
if index > 3 :
break
for i in fun():
print (i)
输出:0 1 2 3

在此例中yield做的事是:

  1:将函数fun的返回值设定为一个生成器

  2:每次运行至yield index 时会将index的值作为生成器的下一个元素返回值for循环并且被赋值给变量i,用print输出出来

简单的yield/send使用描述:

def fun():
index = 0
while True:
value = yield index
print ("value=" + str(value))
print ("index=" + str(index))
index += 1
if index > 3 :
break
funobj = fun()
print (type(funobj))
print ("next=" + str(next(funobj)))
for i in funobj:
print ("i=" + str(i))
try:
funobj.send(i+100)
except StopIteration:
print("it's stop")
输出:

<class 'generator'>
next=0
value=None
index=0
i=1
value=101
index=1
value=None
index=2
i=3
value=103
index=3
it's stop

不是很精通,因此代码有点乱。

解释:

  首先声明了fun函数,并将fun赋给了对面funobj,funobj是一个迭代器。next(funobj)初始化并启动迭代器,程序开始运行fun函数至value = yield index(第一次)结束,yield返回了第一个index值0 next=0

  for i in funobj:启动迭代器,因此此时send还未传值,因此value和next都是空,value=None index=0 程序运行fun函数至value = yield index(第二次)结束,yield返回了第二个index值1 i=1

  注意之后send发送了值101,for再次启动迭代器,从yield启动时捕获到此值101,value=101 index=101。此后类似。

  迭代器结束时会捕获到 StopIteration异常,将此捕获并输出出来 it's stop

简单的yield/send使用描述:

  yeild from语法就是将生成器函数中包括yield语句的部分逻辑封装到一个子生成器函数中。然后在子生成器函数外面可以做一些其他的业务逻辑。整个生成器函数(包括子生成器函数)对外就是一个生成器函数。

def fun():
index = 0
while True:
value = yield index
print ("value=" + str(value))
print ("index=" + str(index))
index += 1
if index > 3 :
break def fun2():
print ("before ")
yield from fun()
print ("end ") funobj = fun2()
print (type(funobj))
print ("next=" + str(next(funobj)))
for i in funobj:
print ("i=" + str(i))
try:
funobj.send(i+100)
except StopIteration:
print("it's stop")

输出:

<class 'generator'>
before
next=0
value=None
index=0
i=1
value=101
index=1
value=None
index=2
i=3
value=103
index=3
end
it's stop

简单的asyncio.coroutine使用描述:(参考自廖雪峰的官方网站

@asyncio.coroutine通过装饰器调用,作用是把一个generator标记为coroutine类型:

import asyncio

@asyncio.coroutine
def hello():
print("Hello world!")
# 异步调用asyncio.sleep(1):
r = yield from asyncio.sleep(1)
print("Hello again!") # 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()

输出:

Hello world!
Hello again!

简单的asyncawait使用描述:

  asyncawait是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:

  1. @asyncio.coroutine替换为async
  2. yield from替换为await

  示例代码:

import asyncio

async def hello():
print("Hello world!")
r = await asyncio.sleep(1)
print("Hello again!") # 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()

  需要注意的是asyncawait只能用在Python 3.5以及后续版本,如果使用3.4版本,则仍需使用asyncio.coroutine和yield from方案。

  示例可能出现的报错如下:

[root@jans test]# python3.6 c.py
Hello world!
Hello again!
[root@jans test]# python3.4 c.py
File "c.py", line 3
async def hello():
^
SyntaxError: invalid syntax

最新文章

  1. 【转】apache 二级域名设置完整步骤
  2. SVN Tree Conflict 的分析
  3. DataGridView很详细的用法(转载)
  4. [fun code - 模拟]孤独的“7”
  5. Ubuntu安装VMware Tools的方法
  6. BZOJ3833 : [Poi2014]Solar lamps
  7. Java Base64编码解码实现
  8. ZOJ 1188 DNA Sorting
  9. JavaScript DOM实战:创建和克隆元素
  10. python 开发利器
  11. java中的引用传递(同样适用于JS)
  12. MySQL执行一个查询的过程
  13. IBM developer:Kafka ACLs
  14. Sublime2 Package Control不可用修复
  15. Emgucv - ImageBox控件
  16. WPF中反转3D列表项
  17. BZOJ3589 动态树(树链剖分+容斥原理)
  18. Java虚拟机八 分析Java堆
  19. 【AGC003F】Fraction of Fractal
  20. Hadoop平台的基本组成与生态系统

热门文章

  1. python的运算符及优先级与python的表达式
  2. Redis的高级应用——数据安全
  3. hdu 1249 三角形 (递推)
  4. win32 application怎么把结果输出到调试窗口
  5. codeforces 1015A
  6. ACM模板~求逆序对的个数
  7. tomcat发布web项目的三种方式
  8. WEB-INF 有关的目录路径问题总结
  9. 如何根据pom.xml文件下载jar包
  10. Chocolatey 使用