一种Pythonic方式,用于更改应从调用cancel()的位置取消异步任务的方式

一种Pythonic方式,用于更改应从调用cancel()的位置取消异步任务的方式,第1张

概述如何从取消任务的位置更改取消任务的行为?我梦dream以求的:task = ensure_future(foo()) def foo_done(task) try: return task.get_result() except CancelError as e: when, why = e.args

如何从取消任务的位置更改取消任务的行为?

我梦dream以求的:

task = ensure_future(foo())def foo_done(task)    try:        return task.get_result()    except CancelError as e:        when,why = e.args        if when == "Now"            # do something...        elif when == "asap":            # do something else...        else:            # do default        print(f"task cancelled because {why}")task.add_done_callback(foo_done)[...]task.cancel("Now","This is an order!")

我可以在调用task.cancel()之前将对象附加到任务,然后再检查它.

task = ensure_future(foo())def foo_done(task)    try:        return task.get_result()    except CancelError as e:        when = getattr(task,"_when","")        why = getattr(task,"_why","")        if when == "Now"            # do something...        elif when == "asap":            # do something else...        else:            # do default        print(f"task cancelled because {why}")task.add_done_callback(foo_done)[...]task._when = "Now"task._why = "This is an order!"task.cancel()

但是在某些情况下,例如当我想捕获正在执行的任务中的CancelError时,它看起来很笨拙:

async def foo():   # some stuff   try:       # some other stuff   except CancellError as e:       # here I have easily access to the error,but not the task :(   [...]

我正在寻找一种更Python化的方式来做到这一点.最佳答案用与异常相关的数据装饰任务的解决方案实际上是一个很好的解决方案.在任务内,您可以使用asyncio.Task.current_task()访问正在处理的任务.

您还可以使用以下装饰器(未经测试)实现您梦dream以求的语法:

def propagate_when(fn):    async def wrapped(*args,**kwds):        try:            return await fn(*args,**kwds)        except CancelledError as e:            e.when = getattr(asyncio.Task.current_task(),'_when',None)            raise    return wrapped

在处理CancelledError时,使用@propagate_when装饰协程可允许foo_done中的代码访问e.when.缺点是e.when在任务内不可用时-您仍然必须使用current_task().由于存在这种不一致,我建议坚持从任务对象读取.

几个相关的建议:

>将取消代码放入存储您传递的对象的实用程序函数中,然后调用task.cancel().这种封装的薄层应该从当前代码中消除“笨拙”的感觉.
>使用带前缀的属性名称-简短而通用的名称,例如_when会在将来的版本中引起冲突. (我知道这只是一个例子,但未加前缀的名称始终有发生冲突的危险.)
>用单个对象装饰任务,将实际数据放入其属性.它使检索变得更简单,更干净,并且使您可以选择在存储的对象上实现方法. 总结

以上是内存溢出为你收集整理的一种Pythonic方式,用于更改应从调用cancel()的位置取消异步任务的方式 全部内容,希望文章能够帮你解决一种Pythonic方式,用于更改应从调用cancel()的位置取消异步任务的方式 所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1199532.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存