我想知道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())
如果在语言核心中有一个更精细的策略就太好了。考虑过这个问题吗?
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问题,我就会更新这个答案。
我的解决方案是:
import threading
class TimeoutError(RuntimeError):
pass
class AsyncCall(object):
def __init__(self, fnc, callback = None):
self.Callable = fnc
self.Callback = callback
def __call__(self, *args, **kwargs):
self.Thread = threading.Thread(target = self.run, name = self.Callable.__name__, args = args, kwargs = kwargs)
self.Thread.start()
return self
def wait(self, timeout = None):
self.Thread.join(timeout)
if self.Thread.isAlive():
raise TimeoutError()
else:
return self.Result
def run(self, *args, **kwargs):
self.Result = self.Callable(*args, **kwargs)
if self.Callback:
self.Callback(self.Result)
class AsyncMethod(object):
def __init__(self, fnc, callback=None):
self.Callable = fnc
self.Callback = callback
def __call__(self, *args, **kwargs):
return AsyncCall(self.Callable, self.Callback)(*args, **kwargs)
def Async(fnc = None, callback = None):
if fnc == None:
def AddAsyncCallback(fnc):
return AsyncMethod(fnc, callback)
return AddAsyncCallback
else:
return AsyncMethod(fnc, callback)
并完全按要求工作:
@Async
def fnc():
pass