Python中的asyncio库盾函数

  

Python中的asyncio库盾函数?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

<强>盾

asyncio。盾,用它可以屏蔽取消操作。一直到这里,我们还没有见识过任务的取消。看一个例子:

拷贝:,loop =, asyncio.get_event_loop ()=:拷贝,task1  loop.create_task (())=:拷贝,task2  loop.create_task (b ())   拷贝:task1.cancel ()   :真的   拷贝:await  asyncio.gather (task1, task2)   Suspending    Suspending  b   ---------------------------------------------------------------------------   CancelledError ,,,,,,,,,,,,,,,,,,,,,,,,,,, Traceback  (most  recent  call 最后)   cell_name  async-def-wrapper拷贝()   CancelledError:

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

拷贝:,await  asyncio.gather (task1, task2,, return_exceptions=True)   :,(concurrent.futures._base.CancelledError (), & # 39; b # 39;]

可以看的到,task2依然会执行完成,但是task1的返回值是一个CancelledError错误,也就是任务被取消了。如果一个创建后就不希望被任何情况取消,可以使用asyncio。盾保护任务能顺利完成。不过要注意一个陷阱,先看错误的写法:

拷贝:,task1 =, asyncio.shield (())=:拷贝,task2  loop.create_task (b ())   拷贝:task1.cancel ()   :真的   拷贝:await  asyncio.gather (task1, task2,, return_exceptions=True)   Suspending    Suspending  b   Resuming  b   :,(concurrent.futures._base.CancelledError (), & # 39; b # 39;]

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

拷贝:,task1 =, asyncio.shield (())=:拷贝,task2  loop.create_task (b ())=:拷贝,ts  asyncio.gather (task1, task2,, return_exceptions=True)   拷贝:task1.cancel ()   :真的   拷贝:await  ts   Suspending    Suspending  b   Resuming    Resuming  b   :,(concurrent.futures._base.CancelledError (), & # 39; b # 39;]

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

先创建GatheringFuture对象ts

取消任务

等待ts

asynccontextmanager

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

得到contextlib  import  contextmanager   async  def  ():   ,,,await  asyncio.sleep (3)   ,,,return  & # 39;一个# 39;   async  def  b ():   ,,,await  asyncio.sleep (1)   ,,,return  & # 39; b # 39;   async  def  s1 ():   ,,,return  await  asyncio.gather ((),, b ())   @contextmanager   def 定时(函数):   ,,,start =, time.perf_counter ()   ,,,油品收率asyncio.run (func ())   ,,,print (f # 39;成本:{time.perf_counter(),背后,开始}& # 39;)

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

拷贝:得到contextmanager  import  *   拷贝:with 定时(s1), as 房车:   …:,,,,,印刷(f # 39;结果:,{房车}& # 39;)   …:   结果:,(& # 39;一个# 39;,,& # 39;b # 39;】   成本:3.0052654459999992

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

@asynccontextmanager   async  def  async_timed(函数):   ,,,start =, time.perf_counter ()   ,,,油品收率await  func ()   ,,,print (f # 39;成本:{time.perf_counter(),背后,开始}& # 39;)   async  def  main ():   ,,,async  with  async_timed (s1), as 房车:   ,,,,,,,印刷(f # 39;结果:,{房车}& # 39;)   拷贝:asyncio.run (main ())   结果:,(& # 39;一个# 39;,,& # 39;b # 39;】   成本:3.00414147500004,

异步版本的,要用异步,另外要注意收益率等待func()这句,相当于产量+等待func ()

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

关于Python中的asyncio库盾函数问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注行业资讯频道了解更多相关知识。

Python中的asyncio库盾函数