Python3.5新增async和await关键字,这里提供用法和例子

根据PEP 492,Python3.5引入关键字async、await。这里给出两个关键字的使用方法。

关键字async、await

async-await的示例。对比在3.5前没有这两个关键字前的编程方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

import asyncio

async def printer():
print("A")
await asyncio.sleep(1)
print("C")

async def printer2():
print("B")
await asyncio.sleep(1)
print("D")

async def main():
await asyncio.wait([printer2(), printer()])

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

  • 在没有async、await前的协程编程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import asyncio

@asyncio.coroutine
def task(n):
yield from asyncio.sleep(1)
print("task {}".format(n))

@asyncio.coroutine
def main():
yield from asyncio.wait([
task(1),
task(2),
task(3)
])

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
  • 使用async、await时
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import asyncio

async def task(n):
await asyncio.sleep(1)
print("task {}".format(n))

async def main():
await asyncio.wait([
task(1),
task(2),
task(3)
])

loop = asyncio.get_event_loop()
loop.run_until_complete(main())

对比可以发现async化简了asyncio.coroutine,await化简了yield from

async for & async with

  • async for 是异步迭代器的语法
  • async with 是with语句(上下文管理器语法)的异步化

async for instance:

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

import random
import asyncio

class AsyncIterable:

def __init__(self):
self.count = 0
self._container = list(range(1, 101))

async def __aiter__(self):
return self

async def __anext__(self):
if self.count >= 5:
raise StopAsyncIteration
data = await self.fetch_data()
self.count += 1
return data

async def fetch_data(self):
return random.choice(self._container)

async def main():
async for data in AsyncIterAble():
print(data)

loop = asyncio.get_event_loop()
loop.run_util_complete(main())

async with instance:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import asyncio
import random

async def task(n):
print("task {}".format(n))

class AsyncContextManager:
async def __aenter__(self):
await log("entering context")

async def __aexit__(self, exc_type, exc, tb):
await log("exiting context")

async def coroutine():
async with AsyncContextManager():
print("inner body")

c = coroutine()

try:
c.send(None)
except StopIteration:
print("end")

Future

Future的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
import asyncio

async def future_demo(future):
await asyncio.sleep(1)
future.set_result('future is done!')

loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(future_demo(future))
loop.run_until_complete(future)

print(future.result())

例子二:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import asyncio

async def future_callback(future):
await asyncio.sleep(1)
future.set_result("future is done!")

def got_result(future):
print(future.result())
loop.stop()

loop = asyncio.get_event_loop()
future = asyncio.Future()
asyncio.ensure_future(future_callback(future))
future.add_done_callback(got_result)

try:
loop.run_forever()
finally:
loop.close()

转载请包括本文地址:https://allenwind.github.io/blog/6363
更多文章请参考:https://allenwind.github.io/blog/archives/