Python异步IO,可以等待/产生整个myFunction()

Python异步IO,可以等待/产生整个myFunction(),python,asynchronous,python-3.5,python-asyncio,Python,Asynchronous,Python 3.5,Python Asyncio,我已经编写了一个对象库,其中许多对象进行HTTP/IO调用。由于安装开销,我一直在考虑转移到asyncio,但我不想重写底层代码 我一直希望将asyncio包装在我的代码中,以便异步执行函数,而不必用wait/yield替换我所有的深层/底层代码 我首先尝试了以下几点: async def my_function1(some_object, some_params): #Lots of existing code which uses existing objects #

我已经编写了一个对象库,其中许多对象进行HTTP/IO调用。由于安装开销,我一直在考虑转移到asyncio,但我不想重写底层代码

我一直希望将asyncio包装在我的代码中,以便异步执行函数,而不必用wait/yield替换我所有的深层/底层代码

我首先尝试了以下几点:

async def my_function1(some_object, some_params):
      #Lots of existing code which uses existing objects
      #No await statements
      return output_data

async def my_function2():
      #Does more stuff

while True:
    loop = asyncio.get_event_loop()
    tasks = my_function(some_object, some_params), my_function2()
    output_data = loop.run_until_complete(asyncio.gather(*tasks))
    print(output_data)
我很快意识到,虽然这段代码在运行,但实际上没有任何事情是异步发生的,函数是同步完成的。我对异步编程非常陌生,但我认为这是因为我的两个函数都没有使用关键字wait或yield,因此这些函数不是cootroutines,也不是yield,因此没有机会移动到不同的cootroutine。如果我错了,请纠正我

我的问题是,是否可以将复杂的函数(在函数内部深处进行HTTP/IO调用)封装在
asyncio
wait
关键字中,例如

async def my_function():
    print("Welcome to my function")
    data = await bigSlowFunction()
更新-遵循卡尔森的回答

由于卡尔森公司接受了以下答案,我使用了以下代码,该代码运行良好:

from concurrent.futures import ThreadPoolExecutor
import time    

#Some vars
a_var_1 = 0
a_var_2 = 10

pool = ThreadPoolExecutor(3)

future = pool.submit(my_big_function, object, a_var_1, a_var_2)
while not future.done() :
    print("Waiting for future...")
    time.sleep(0.01)
print("Future done")
print(future.result())

这非常好用,
future.done()
/sleep循环让您知道通过异步可以使用多少CPU周期。

简单的回答是,如果不在代码中明确标记控制可以传递回事件循环的点,您就无法获得
asyncio
的好处。这是通过将IO繁重的函数转换为协同程序来实现的,就像您假设的那样

在不改变现有代码的情况下,您可能会通过greenlets实现您的目标(看看或)

另一种可能是利用Python的包装功能,将对已经编写的函数的调用传递给一些人,并产生最终的结果。请注意,这是多线程编程的所有警告

类似于

from concurrent.futures import ThreadPoolExecutor

from thinair import big_slow_function

executor = ThreadPoolExecutor(max_workers=5)

async def big_slow_coroutine():
    await executor.submit(big_slow_function)

从Python3.9开始,您可以使用
asyncio.to_thread()
将阻塞(非异步)函数包装到协同程序中,使其成为可等待的。表中给出的示例为:


这似乎比使用
concurrent.futures
创建协同程序更像是一种联合方法,但我还没有对它进行过广泛的测试。

感谢您的回复,我将看看将低级代码更改为异步是否可行。同时感谢您提出的备选方案,这些方案可能更容易实施。
def blocking_io():
    print(f"start blocking_io at {time.strftime('%X')}")
    # Note that time.sleep() can be replaced with any blocking
    # IO-bound operation, such as file operations.
    time.sleep(1)
    print(f"blocking_io complete at {time.strftime('%X')}")

async def main():
    print(f"started main at {time.strftime('%X')}")

    await asyncio.gather(
        asyncio.to_thread(blocking_io),
        asyncio.sleep(1))

    print(f"finished main at {time.strftime('%X')}")


asyncio.run(main())

# Expected output:
#
# started main at 19:50:53
# start blocking_io at 19:50:53
# blocking_io complete at 19:50:54
# finished main at 19:50:54