python_协程_async_await新特性
东西都在demo中
import asyncio
import random
import time
from threading import currentThread
animals = ['佩奇', '乔治', '吉吉']
def run_time(func: any) -> any:
def _():
st: float = time.time()
func()
print('{} 运行用时: {:.2f}秒'.format(func.__name__, time.time() - st))
return _
@run_time
def demo1():
def eat(animal: str):
# 这里模拟吃东西
t: int = random.randint(1, 2)
print('{} 开始吃东西'.format(animal))
time.sleep(t)
print('{} 花费了{}秒, 吃完东西了'.format(animal, t))
for animal in animals:
eat(animal)
@run_time
def demo2():
async def eat(animal: str):
# 这里模拟吃东西
print('{} 开始吃东西'.format(animal))
t: int = random.randint(1, 2)
time.sleep(t)
print('{} 花费了{}秒, 吃完东西了'.format(animal, t))
for animal in animals:
eat(animal)
@run_time
def demo3():
async def eat(animal: str):
# 这里模拟吃东西
print('{} 开始吃东西'.format(animal))
t: int = random.randint(1, 2)
await time.sleep(t)
print('{} 花费了{}秒, 吃完东西了'.format(animal, t))
for animal in animals:
eat(animal)
@run_time
def demo4():
async def sleep(_t):
# 定义一个异步函数用来实现异步操作
await asyncio.sleep(_t)
return _t
async def eat(animal: str) -> str:
# 这里模拟吃东西
print('{} 开始吃东西, {}'.format(animal, currentThread()))
t: int = random.randint(1, 2)
# 一个异步的函数, 也是可等待的对象
_t = await sleep(t)
print('{} 花费了{}秒, 吃完东西了'.format(animal, _t))
return animal
# # 执行多个任务
# # 1. 创建一个事件循环
# loop = asyncio.get_event_loop()
# # 2. 加入事件队列
# tasks:list[any] = []
# for animal in animals:
# tasks.append(eat(animal))
# # 3. 执行事件队列, 直到最晚的一个事件被处理完毕后结束
# loop.run_until_complete(asyncio.wait(tasks))
# # # 获得返回值
# # 1. 创建一个事件循环
# loop = asyncio.get_event_loop()
# # 2. 创建一个事件
# task = loop.create_task(eat(animals[0]))
# # 3. 执行事件
# loop.run_until_complete(task)
# # 4. 获取事件返回值
# print(task.result())
# 获取多个任务返回值(
# 1. 创建一个事件循环
loop = asyncio.get_event_loop()
# 2. 循环创建事件,并加入队列
tasks: list[any] = []
for animal in animals:
task: any = loop.create_task(eat(animal))
tasks.append(task)
# 3. 执行事件队列
loop.run_until_complete(asyncio.wait(tasks))
# 4. 获得所有事件返回值
print([i.result() for i in tasks])
if __name__ == '__main__':
demo4()
# 假设我们有三个小动物需要吃东西,但是只有一个人来喂食
# demo1中, 每个小动物在吃完之后才喂下一个小动物吃东西,这叫做(串行),大部分时间都花在挨个等的时间了
# demo2中, 使用async让函数函数变成异步函数,避免了无谓的等待, 但是却忘了定义喂这个小动物撒完食物之后该什么时候离开(是不是该喂其他小动物了呢?),这样会就造成了还是串行(实际上demo2是无法运行的这里只是比喻)
# demo3中, 使用await来决定什么时候离开喂养下一个小动物,但是还是和 demo2 一样无法运行, 原因是, await 后面必须跟一个 awaitable 类型或者具有 __await__ 属性的对象. 这个 awaitable, 并不是我们认为 time.sleep() 是 awaitable 就可以 await 了,常见的 awaitable 对象应该是await asyncio.sleep
# demo4中, 如果调用异步函数, 使用 asyncio 库中的事件循环机制来启动(详情见demo4 详解)