韩漫免费漫画在线观看方法,《好好疼爱里面》免费看,年轻漂亮的女士护士内衣,妈妈醉酒后把我当爸爸电视剧

文章 > Python高级 > 深究Python中的asyncio库-shield函数

深究Python中的asyncio库-shield函数

Python

头像

Python

2019-06-04 11:05:405803浏览 · 0收藏 · 0评论

shield

asyncio.shield,用它可以屏蔽取消操作。一直到这里,我们还没有见识过Task的取消。

看一个例子:

In : loop = asyncio.get_event_loop()
In : task1 = loop.create_task(a())
In : task2 = loop.create_task(b())
In : task1.cancel()
Out: True
In : await asyncio.gather(task1, task2)
Suspending a
Suspending b
---------------------------------------------------------------------------
CancelledError                            Traceback (most recent call last)
cell_name in async-def-wrapper()
CancelledError:

在上面的例子中,task1被取消了后再用asyncio.gather收集结果,直接抛CancelledError错误了。这里有个细节,gather支持return_exceptions参数:

In : await asyncio.gather(task1, task2, return_exceptions=True)
Out: [concurrent.futures._base.CancelledError(), 'B']

可以看到,task2依然会执行完成,但是task1的返回值是一个CancelledError错误,也就是任务被取消了。如果一个创建后就不希望被任何情况取消,可以使用asyncio.shield?;と挝衲芩忱瓿?。不过要注意一个陷阱,先看错误的写法:

In : task1 = asyncio.shield(a())
In : task2 = loop.create_task(b())
In : task1.cancel()
Out: True
In : await asyncio.gather(task1, task2, return_exceptions=True)
Suspending a
Suspending b
Resuming b
Out: [concurrent.futures._base.CancelledError(), 'B']

可以看到依然是CancelledError错误,且协程a未执行完成,正确的用法是这样的:

In : task1 = asyncio.shield(a())
In : task2 = loop.create_task(b())
In : ts = asyncio.gather(task1, task2, return_exceptions=True)
In : task1.cancel()
Out: True
In : await ts
Suspending a
Suspending b
Resuming a
Resuming b
Out: [concurrent.futures._base.CancelledError(), 'B']

可以看到虽然结果是一个CancelledError错误,但是看输出能确认协程实际上是执行了的。所以正确步骤是:

先创建 GatheringFuture 对象 ts

取消任务

await ts

asynccontextmanager

如果你了解Python,之前可能听过或者用过contextmanager ,一个上下文管理器。通过一个计时的例子就理解它的作用:

from contextlib import contextmanager
async def a():
    await asyncio.sleep(3)
    return 'A'
async def b():
    await asyncio.sleep(1)
    return 'B'
async def s1():
    return await asyncio.gather(a(), b())
@contextmanager
def timed(func):
    start = time.perf_counter()
    yield asyncio.run(func())
    print(f'Cost: {time.perf_counter() - start}')

timed函数用了contextmanager装饰器,把协程的运行结果yield出来,执行结束后还计算了耗时:

In : from contextmanager import *
In : with timed(s1) as rv:
...:     print(f'Result: {rv}')
...:
Result: ['A', 'B']
Cost: 3.0052654459999992

大家先体会一下。在Python 3.7添加了asynccontextmanager,也就是异步版本的contextmanager,适合异步函数的执行,上例可以这么改:

@asynccontextmanager
async def async_timed(func):
    start = time.perf_counter()
    yield await func()
    print(f'Cost: {time.perf_counter() - start}')
async def main():
    async with async_timed(s1) as rv:
        print(f'Result: {rv}')
In : asyncio.run(main())
Result: ['A', 'B']
Cost: 3.00414147500004

async版本的with要用async with,另外要注意yield await func()这句,相当于yield + await func()

PS: contextmanager 和 asynccontextmanager 最好的理解方法是去看源码注释

下一节:深究Python中的asyncio库-函数的回调与调度

关注

关注公众号,随时随地在线学习

本教程部分素材来源于网络,版权问题联系站长!

老赵在货车把儿媳妇送到了| 暴躁妹妹CSGO直播| 李秀晶| 蜜桃成熟时在线观看| 一线产区和二线产区的标准图 | 《湿点》未增减板相似| 姐姐片多多免费高清电视剧 | 雨后小故事贴吧| 女被扒开腿狂躁XXXXX视频| 晚上打扑克视频| 《湿点》未增减板相似| 我穿水K被同桌C出水了H漫画| 《魅魔之耻》1~4集免费看| 雨后的故事动态图| 免费双男主做酱酱酿酿的动漫| INDEX.PHP| 美女和帅哥一起努力生产豆浆| 办公室的滋润3| 天秤座运势| 坤坤寒入桃子里电视剧| 主人~我错了请把它关掉歌词| 我把校花嘴巴当套子的小说| 午马影视免费观看电视剧| 美国伦理性淫梦| 母亲和女婿免费高清电视剧 | 蜜桃成熟时2| 老妇人50-60-70-80| 妈妈出轨了免费观看电视剧全集 | 《疯狂72小时》韩剧| 妈妈叫我戴上避孕套是什么歌| 虹色时光| 黄金网站软件APP| 《巨大荫蒂》免费| 女子蹲下尿裤子的视频| 16岁女儿与父亲一起做饭| 国产一区| 金瓶双艳| C2000论坛| 台剧《恋爱之瘾》林教授在线观看 | 福艳都市韵母王雪琴| 老公拿狗给我配