首页 编程与技术
浅析 python 协程相关概念
这里有新鲜出炉的 Python3 官方中文指南, 程序狗速度看过来!
Python 编程语言
Python 是一种面向对象解释型计算机程序设计语言, 由 Guido van Rossum 于 1989 年底发明, 第一个公开发行版发行于 1991 年 Python 语法简洁而清晰, 具有丰富和强大的类库它常被昵称为胶水语言, 它能够把用其他语言制作的各种模块 (尤其是 C/C++) 很轻松地联结在一起
本篇文章给大家分析了一下 python 协程的概念以及代码相关实例, 有兴趣的朋友跟着小编学习下吧
这篇文章是读者朋友的 python 协程的学习经验之谈, 以下是全部内容:
协程的历史说来话长, 要从生成器开始讲起
如果你看过我之前的文章 python 奇遇记: 迭代器和生成器 , 对生成器的概念应该很了解生成器节省内存, 用的时候才生成结果
# 生成器表达式
a = (x*x for x in range(10))
# next 生成值
next(a()) # 输出 0
next(a()) # 输出 1
next(a()) # 输出 4
与生成器产出数据不同的是, 协程在产出数据的同时还可以接收数据, 具体来说就是把 yield 放在了表达式的右边我们可以使用. send() 把数据发送给协程函数
def writer():
print('-> coroutine started')
for i in range(8):
w = yield
print(i+w)
w = writer()
# 本质还是生成器
>>> w
<generator object writer at 0x000002595BC57468>
# 首先要用 next() 把协程激活
>>> next(w)
-> coroutine started
# 发送数据
>>> w.send(1)
1
# send 到第八次之后会抛出异常
# 因为协程已经结束了
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
第一步必须使用 next() 激活协程函数, 这样才能在下一步使用. send() 发送数据
可以看到, 在第 8 次接收完数据之后, 会产生结束的异常, 因为程序流程结束了, 这是正常现象加个异常处理即可如果需要在两个协程间传递数据呢?
def writer():
while True:
w = yield
print('>>', w)
def writer_wrapper(coro):
# 激活
next(coro)
while True:
# 异常处理
try:
x = yield
# 发送数据给 writer
coro.send(x)
except StopIteration:
pass
w = writer()
wrap = writer_wrapper(w)
# 激活
next(wrap)
for i in range(4):
wrap.send(i)
# 输出
>> 0
>> 1
>> 2
>> 3
上面的代码中, 数据首先传递到 writer_wrapper, 之后再传递到 writer
data>writer_wrapper>writer
可以这么写, 不过, 又要预先激活, 又要加异常, 看起来有点麻烦啊 yield from 的出现可以解决这个问题, 同样是传递数据:
def writer():
while True:
w = yield
print('>>', w)
def writer_wrapper2(coro):
yield from coro
一行代码解决问题
总之, yield from 相当于提供了一个通道, 使得数据可以在协程之间流转 writer_wrapper2 中使用 yield from coro 时, coro 此时获得控制权, 在我们. send() 数据时, writer_wrapper2 被阻塞, 直到 writer 打印出结果
在这个阶段, 协程本质上还是由生成器构成的
即使我们使用 yield from 简化了流程, 协程和生成器的知识理解起来还是有点懵逼, 而且 yield from 用在异步编程中有诸多不顺 (asyncio 以前就是用 yield from), 于是在 3.5 版本的 python 中, 弃用了 yield from , 新加入了两个关键字 async 和 await , 同时协程不再是生成器类型, 而是原生的协程类型
现在我们定义一个协程要像下面这样:
async def func():
await 'some code'
不用于异步的协程该怎么用, 我还不知道所以, 协程的介绍到这里就结束啦感谢你对 PHPERZ 的支持
您可能感兴趣的文章:
Python 并发编程协程 (Coroutine) 之 Gevent 详解
Python 协程的用法和例子详解
python 生成器协程运算实例
Tornado 协程在 python2.7 如何返回值 (实现方法)
python 简单线程和协程学习心得 (分享)
python 并发编程之多进程多线程异步和协程详解
python 线程进程和协程详解
深入浅析 python 中的多进程多线程协程
简述 Python 中的进程线程协程
python 协程用法实例分析
简单介绍 Python 的 Tornado 框架中的协程异步实现原理
来源: http://www.phperz.com/article/18/0201/362973.html