我想知道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())

如果在语言核心中有一个更精细的策略就太好了。考虑过这个问题吗?


当前回答

您可以使用Python 2.6中添加的多处理模块。您可以使用进程池,然后通过以下方式异步获取结果:

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

例如:

from multiprocessing import Pool

def f(x):
    return x*x

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

这只是一种选择。这个模块提供了很多工具来实现你想要的。此外,它将很容易从这做一个装饰。

其他回答

您可以使用Python 2.6中添加的多处理模块。您可以使用进程池,然后通过以下方式异步获取结果:

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

例如:

from multiprocessing import Pool

def f(x):
    return x*x

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

这只是一种选择。这个模块提供了很多工具来实现你想要的。此外,它将很容易从这做一个装饰。

有什么理由不使用线程吗?您可以使用线程类。 使用isAlive()函数代替finished()函数。result()函数可以join()线程并检索结果。并且,如果可以的话,重写run()和__init__函数来调用构造函数中指定的函数,并将值保存到类实例的某个地方。

喜欢的东西:

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上的文档。

从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()

2021年的原生Python异步调用方式,Python 3.9也适用于Jupyter / Ipython内核

Camabeh的答案是从Python 3.3开始的。

异步def display_date(循环): End_time = loop.time() + 5.0 而真正的: print (datetime.datetime.now ()) If (loop.time() + 1.0) >= end_time: 打破 等待asyncio.sleep (1) Loop = asyncio.get_event_loop() #阻塞调用,当display_date()协程完成时返回 loop.run_until_complete (display_date(循环) loop.close ()

这将在Jupyter笔记本/ Jupyter实验室工作,但抛出一个错误:

RuntimeError: This event loop is already running

由于Ipython使用事件循环,我们需要一些嵌套异步循环,这在Python中还没有实现。幸运的是,有nest_asyncio来处理这个问题。你所需要做的就是:

!pip install nest_asyncio # use ! within Jupyter Notebook, else pip install in shell
import nest_asyncio
nest_asyncio.apply()

(基于此线程)

只有在调用loop.close()时,它才会抛出另一个错误,因为它可能指向Ipython的主循环。

RuntimeError: Cannot close a running event loop

一旦有人回答了这个github问题,我就会更新这个答案。