python async await报错_Python3.5中引入的async和await

本文介绍了Python3.5引入的async和await关键字,它们使得异步编程更加简洁。通过示例展示了如何使用asyncio模块创建协程,以及如何使用async/await替代@asyncio.coroutine和yield from。同时强调了async只能用于定义协程,而不能将生成器转换为协程,最后演示了如何结合事件循环运行协程任务。
摘要由CSDN通过智能技术生成

先来一个asyncio程序

import asyncio,random

@asyncio.coroutine

def smart_fib(n):

index = 0

a = 0

b = 1

while index < n:

sleep_secs = random.uniform(0, 0.2)

yield from asyncio.sleep(sleep_secs) #通常yield from后都是接的耗时操作

print('Smart one think {} secs to get {}'.format(sleep_secs, b))

a, b = b, a + b

index += 1

@asyncio.coroutine

def stupid_fib(n):

index = 0

a = 0

b = 1

while index < n:

sleep_secs = random.uniform(0, 0.4)

yield from asyncio.sleep(sleep_secs) #通常yield from后都是接的耗时操作

print('Stupid one think {} secs to get {}'.format(sleep_secs, b))

a, b = b, a + b

index += 1

if __name__ == '__main__':

loop = asyncio.get_event_loop()

tasks = [

smart_fib(10),

stupid_fib(10),

]

loop.run_until_complete(asyncio.wait(tasks))

print('All fib finished.')

loop.close()

asyncio.wait()监听一个协程任务列表

yield from后面接的asyncio.sleep()是一个coroutine(里面也用了yield from),所以线程不会等待asyncio.sleep(),而是直接中断并执行下一个消息循环。当asyncio.sleep()返回时,线程就可以从yield from拿到返回值(此处是None),然后接着执行下一行语句。

asyncio是一个基于事件循环的实现异步I/O的模块。通过yield from,我们可以将协程asyncio.sleep的控制权交给事件循环,然后挂起当前协程;之后,由事件循环决定何时唤醒asyncio.sleep,接着向后执行代码。

协程之间的调度都是由事件循环决定。

yield from asyncio.sleep(sleep_secs) 这里不能用time.sleep(1)因为time.sleep()返回的是None,它不是iterable,还记得前面说的yield from后面必须跟iterable对象(可以是生成器,迭代器)。

async和await

弄清楚了asyncio.coroutine和yield from之后,在Python3.5中引入的async和await就不难理解了:可以将他们理解成asyncio.coroutine/yield from的完美替身。当然,从Python设计的角度来说,async/await让协程表面上独立于生成器而存在,将细节都隐藏于asyncio模块之下,语法更清晰明了。

加入新的关键字 async ,可以将任何一个普通函数变成协程

import time,asyncio,random

async def mygen(alist):

while len(alist) > 0:

c = randint(0, len(alist)-1)

print(alist.pop(c))

a = ["aa","bb","cc"]

c=mygen(a)

print(c)

输出:

在上面程序中,我们在前面加上async,该函数就变成一个协程了。

但是async对生成器是无效的。async无法将一个生成器转换成协程。

还是刚才那段代码,我们把print改成yield

async def mygen(alist):

while len(alist) > 0:

c = randint(0, len(alist)-1)

yield alist.pop(c)

a = ["ss","dd","gg"]

c=mygen(a)

print(c)

可以看到输出

并不是coroutine 协程对象

所以我们的协程代码应该是这样的

import time,asyncio,random

async def mygen(alist):

while len(alist) > 0:

c = random.randint(0, len(alist)-1)

print(alist.pop(c))

await asyncio.sleep(1)

strlist = ["ss","dd","gg"]

intlist=[1,2,5,6]

c1=mygen(strlist)

c2=mygen(intlist)

print(c1)

要运行协程,要用事件循环

在上面的代码下面加上:

if __name__ == '__main__':

loop = asyncio.get_event_loop()

tasks = [

c1,

c2

]

loop.run_until_complete(asyncio.wait(tasks))

print('All fib finished.')

loop.close()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值