我正在编写一个框架,该框架将调用用户提供的函数。
我想允许使用的提供的功能是以下任何一种:
- 一个普通函数
- 返回CCD_ 1的函数
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
然后像这样在框架中调用用户提供的函数CCD_ 5:
res = yield from maybe_async(f(x))
这将任何纯函数返回值封装到Future
中-始终。我对这件事的表现或其他影响持谨慎态度。
以上是"推荐"的方式吗?
此外,上面代码的"内联"版本没有这个开销。我如何才能做到两者的最佳效果:在"普通"情况下没有开销,但在整个框架中检查异步返回时没有代码重复?
总之,似乎有两个(主要)选项:
习语1:
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)
您可以编写asyncio.iscoroutine(value),而不是isistance(value,types.GeneratorType):https://docs.python.org/dev/library/asyncio-task.html#asyncio.iscoroutine