2015-12-20 52 views
9

我想从python coroutine中使用ThreadPoolExecutor,将一些阻塞网络调用委托给单独的线程。然而,运行下面的代码:等待执行者的未来:未来不能用于'等待'表达式

from concurrent.futures import ThreadPoolExecutor 
import asyncio 

def work(): 
    # do some blocking io 
    pass 

async def main(): 
    executor = ThreadPoolExecutor() 
    await executor.submit(work) 

loop = asyncio.get_event_loop() 
loop.run_until_complete(main()) 
loop.close() 

原因错误:

TypeError: object Future can't be used in 'await' expression 

是不是Future对象awaitable?为什么说他们不是?

如何才能await a Future对象由executor.submit返回?

的Python 3.5.0

编辑

使用executor.submit是不是我的决定。这由几个库在内部使用,如requests-futures。我正在寻找一种与协程中的模块进行交互的方法。

回答

17

你应该使用loop.run_in_executor

from concurrent.futures import ThreadPoolExecutor 
import asyncio 

def work(): 
    # do some blocking io 
    pass 

async def main(loop): 
    executor = ThreadPoolExecutor() 
    await loop.run_in_executor(executor, work) 

loop = asyncio.get_event_loop() 
loop.run_until_complete(main(loop)) 
loop.close() 

编辑

concurrent.futures.Future对象来自不同asyncio.Futureasyncio.Future旨在用于事件循环,并且是等待,而前者不是。 loop.run_in_executor提供了两者之间的必要的互操作性。

编辑#2

Using executor.submit is not my decision. This is used internally by several libraries, like requests-futures. I am searching for a way to interop with those modules from coroutines.

虽然无证,您可以使用asyncio.wrap_future(future, *, loop=None)concurrent.futures.Future转换为asyncio.Future

+1

我不知道为什么downvote。这当然有效。不过,我更感兴趣的是*为什么而不是*如何*。另外,我使用了期货请求库,它使用内部提交。 –

+0

简单*为什么*是'concurrent.futures.Future'不等待。你正在考虑'asyncio.Future'。 –

+0

好的,所以我们有不同的类型称为未来。这些类型之间是否存在转换? –