Python的异步回调和发电机 [英] Python asynchronous callbacks and generators

查看:163
本文介绍了Python的异步回调和发电机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想转换一个同步库使用内部异步IO架构。我有几种方法是这样的:

I'm trying to convert a synchronous library to use an internal asynchronous IO framework. I have several methods that look like this:

def foo:
  ....
  sync_call_1()   # synchronous blocking call
  ....
  sync_call_2()   # synchronous blocking call
  ....
  return bar

对于每个同步功能( sync_call _ * ),我写了一个相应的异步函数,它接受一个回调。例如。

For each of the synchronous functions (sync_call_*), I have written a corresponding async function that takes a a callback. E.g.

def async_call_1(callback=none):
  # do the I/O
  callback()

现在的巨蟒新手问题 - 什么最简单的方法,以现有的方法转化,而不是使用这些新的异步方法?也就是说,该方法富()上述需要现在是:

Now for the python newbie question -- whats the easiest way to translate the existing methods to use these new async methods instead? That is, the method foo() above needs to now be:

def async_foo(callback):
  # Do the foo() stuff using async_call_*
  callback()

一个显而易见的选择是一个回调传递到有效地恢复调用foo的功能各异步方法,然后再调用回调在方法的最后全球性的。然而,这使得code脆,丑陋,我需要添加一个新的回调每次调用 async_call _ * 方法。

有没有一种简单的方法来做到这一点使用蟒蛇成语,如发电机或协程?

Is there an easy way to do that using a python idiom, such as a generator or coroutine?

推荐答案

更新:用一粒盐借此,因为我出了现代化的蟒蛇异步发展,包括<触摸的HREF =htt​​p://www.gevent.org/相对=nofollow> GEVENT 和的 ASYNCIO 并没有真正与异步code认真体会。

UPDATE: take this with a grain of salt, as I'm out of touch with modern python async developments, including gevent and asyncio and don't actually have serious experience with async code.

有线程较少异步代码在Python 3常见的方法:

There are 3 common approaches to thread-less async coding in Python:


  1. 回调 - 丑陋,但可行的,扭曲的做这口井

  1. Callbacks - ugly but workable, Twisted does this well.

发电机 - 不错,但需要的所有的您code遵循风格

Generators - nice but require all your code to follow the style.

使用Python实现与现实的任务蕾 - 无堆栈(RIP)和 greenlet <。 / p>

Use Python implementation with real tasklets - Stackless (RIP) and greenlet.

不幸的是,理想情况下整个程序应该使用一种风格,或事情变得复杂。如果你与你的库露出一个完全同步接口OK,你可能是好的,但如果你想多次打电话给你库并联的其他的异步code的工作,尤其是在并行,那么你需要一个公共事件反应器,可以与所有的code工作。

Unfortunately, ideally the whole program should use one style, or things become complicated. If you are OK with your library exposing a fully synchronous interface, you are probably OK, but if you want several calls to your library to work in parallel, especially in parallel with other async code, then you need a common event "reactor" that can work with all the code.

所以,如果你有(或期望用户有)其他异步code在应用程序中,采用相同的模式可能是聪明的。

So if you have (or expect the user to have) other async code in the application, adopting the same model is probably smart.

如果你不想了解整个混乱,可以考虑使用坏旧线程。他们还难看,但一切工作。

If you don't want to understand the whole mess, consider using bad old threads. They are also ugly, but work with everything else.

如果你想了解如何协同程序可以帮助你 - 他们会如何复杂,大卫Beazley的A在协同程序和并发好奇课程是好东西。

If you do want to understand how coroutines might help you - and how they might complicate you, David Beazley's "A Curious Course on Coroutines and Concurrency" is good stuff.

Greenlets 可能actualy最干净的方式,如果你可以使用该扩展。我没有跟他们任何经验,所以不能多说。

Greenlets might be actualy the cleanest way if you can use the extension. I don't have any experience with them, so can't say much.

这篇关于Python的异步回调和发电机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆