4

我正在编写一个框架,该框架将调用用户提供的函数。

我想允许使用提供的函数是以下任何一种:

  • 一个简单的函数
  • 一个函数返回asyncio.Future
  • 一个asyncio.coroutine

即用户函数既可以是同步的,也可以是异步的,框架事先并不知道,但需要应对所有的变体。

Twisted为此 defer.maybeDeferred。会有什么asyncio办法?

我有类似以下的内容(完整代码在这里):

import types
types.GeneratorType

def maybe_async(value):
   if isinstance(value, types.GeneratorType) or \
      isinstance(value, asyncio.futures.Future):
      return value
   else:
      future = asyncio.Future()
      future.set_result(value)
      return future

然后f在框架中像这样调用用户提供的函数:

res = yield from maybe_async(f(x))

这将任何普通函数返回值包装到-alwaysFuture中。我对此表现或其他影响持谨慎态度。

是上面的“推荐”方式吗?

此外,上述代码的“内联”版本没有这种开销。我怎样才能达到两者的最佳状态:“普通”情况下没有开销,但在整个框架中检查异步返回时没有代码重复?

4

2 回答 2

2

总而言之,似乎有两个(主要)选项:

成语一:

res = f(x)
if yields(res):
   res = yield from res

在哪里

def yields(value):
   return isinstance(value, asyncio.futures.Future) or inspect.isgenerator(value)

或者

成语2:

res = yield from asyncio.coroutine(f)(x)
于 2013-12-23T11:38:25.363 回答
0

代替 isinstance(value, types.GeneratorType),你可以写 asyncio.iscoroutine(value): https ://docs.python.org/dev/library/asyncio-task.html#asyncio.iscoroutine

于 2014-11-28T11:50:44.173 回答