Python中的异步方法调用?

222 投票
14 回答
334610 浏览
提问于 2025-04-15 13:25

我在想,Python有没有什么库可以用来进行异步方法调用。如果能像下面这样做就太好了:

@async
def longComputation():
    <code>


token = longComputation()
token.registerCallback(callback_function)
# alternative, polling
while not token.finished():
    doSomethingElse()
    if token.finished():
        result = token.result()

或者用异步的方式调用一个不是异步的例程:

def longComputation()
    <code>

token = asynccall(longComputation())

如果语言本身能有一个更完善的策略就好了。这有没有被考虑过呢?

14 个回答

75

从Python 3.5开始,你可以为异步函数使用增强版的生成器。

import asyncio
import datetime

增强版生成器的语法:

@asyncio.coroutine
def display_date(loop):
    end_time = loop.time() + 5.0
    while True:
        print(datetime.datetime.now())
        if (loop.time() + 1.0) >= end_time:
            break
        yield from asyncio.sleep(1)


loop = asyncio.get_event_loop()
# Blocking call which returns when the display_date() coroutine is done
loop.run_until_complete(display_date(loop))
loop.close()

新的 async/await 语法:

async def display_date(loop):
    end_time = loop.time() + 5.0
    while True:
        print(datetime.datetime.now())
        if (loop.time() + 1.0) >= end_time:
            break
        await asyncio.sleep(1)


loop = asyncio.get_event_loop()
# Blocking call which returns when the display_date() coroutine is done
loop.run_until_complete(display_date(loop))
loop.close()
231

类似这样的:

import threading

thr = threading.Thread(target=foo, args=(), kwargs={})
thr.start() # Will run "foo"
....
thr.is_alive() # Will return whether foo is running currently
....
thr.join() # Will wait till "foo" is done

想了解更多细节,可以查看文档:https://docs.python.org/library/threading.html

156

你可以使用在Python 2.6中新增的 multiprocessing模块。这个模块可以让你使用多个进程池,然后异步地获取结果,方法是:

apply_async(func[, args[, kwds[, callback]]])

例如:

import time
from multiprocessing import Pool

def postprocess(result):
    print("finished: %s" % result)

def f(x):
    return x*x

if __name__ == '__main__':
    pool = Pool(processes=1)              # Start a worker processes.
    result = pool.apply_async(f, [10], callback=postprocess) # Evaluate "f(10)" asynchronously calling callback when finished.
    print("waiting...")
    time.sleep(1)

这只是其中一种选择。这个模块提供了很多功能,可以帮助你实现想要的效果。而且,从这个模块创建一个装饰器也会非常简单。

撰写回答