用于ioloop的Python 3.5异步块
我有一个带有两个处理程序的简单aiohttp服务器。 第一个在用于ioloop的Python 3.5异步块,python,python-3.x,async-await,python-asyncio,aiohttp,Python,Python 3.x,Async Await,Python Asyncio,Aiohttp,我有一个带有两个处理程序的简单aiohttp服务器。 第一个在异步for循环中进行一些计算。第二个只返回文本响应not_so_long_操作以最慢的递归实现返回第30个斐波那契数,大约需要1秒的时间 def not_so_long_operation(): return fib(30) class arange: def __init__(self, n): self.n = n self.i = 0 async def __aiter
异步for
循环中进行一些计算。第二个只返回文本响应not_so_long_操作
以最慢的递归实现返回第30个斐波那契数,大约需要1秒的时间
def not_so_long_operation():
return fib(30)
class arange:
def __init__(self, n):
self.n = n
self.i = 0
async def __aiter__(self):
return self
async def __anext__(self):
i = self.i
self.i += 1
if self.i <= self.n:
return i
else:
raise StopAsyncIteration
# GET /
async def index(request):
print('request!')
l = []
async for i in arange(20):
print(i)
l.append(not_so_long_operation())
return aiohttp.web.Response(text='%d\n' % l[0])
# GET /lol/
async def lol(request):
print('request!')
return aiohttp.web.Response(text='just respond\n')
def not_so_long_操作():
返回fib(30)
阿兰奇班:
定义初始化(self,n):
self.n=n
self.i=0
异步定义(自):
回归自我
异步定义(自):
i=自我
self.i+=1
如果self.i这里实际上不需要异步迭代器。相反,您可以简单地将控件返回到循环中的事件循环。在python 3.4中,这是通过使用一个简单的yield
:
@asyncio.coroutine
def index(self):
for i in range(20):
not_so_long_operation()
yield
在python 3.5中,您可以定义一个空的
对象,该对象基本上执行相同的操作:
class Empty:
def __await__(self):
yield
然后将其与wait
语法一起使用:
async def index(request):
for i in range(20):
not_so_long_operation()
await Empty()
或者简单地使用:
您还可以使用以下命令在线程中运行not\u so\u long\u操作
:
由于,fib(30)
受CPU限制,共享的数据很少,因此您可能应该使用(与ThreadPoolExecutor相反)
:
创建应用程序时设置executor
:
app = Application(...)
app["exector"] = ProcessPoolExector()
您的示例没有用于在任务之间切换的屈服点(await
语句)。
异步迭代器允许在\uuuu aiter\uuuu
/\uuu anext\uuuu
中使用等待
,但不自动将其插入代码中
说
class arange:
定义初始化(self,n):
self.n=n
self.i=0
异步定义(自):
回归自我
异步定义(自):
i=自我
self.i+=1
如果self.i每次都需要构造空对象吗?创建next\u tick=Empty()
然后与wait next\u tick
一起使用可以吗?@MichaelIhnatenko当然可以,尽管我很惊讶在python 3.5中没有标准的方法将控件返回到事件循环,添加了async for
,以避免与内部协同程序中使用的StopIteration
发生冲突?不完全是这样async for
使用\uuuu aiter\uuuu
/\uuuu anext\uuuu
一对协同路由。假设我们从数据库中读取了大量数据(比如)。它获取大量数据,逐项返回,并在数据耗尽时获取下一批数据。在wait
语句的帮助下,您可以在\uuu aiter\uuuu
协同程序中执行I/O,但在旧的good\uuuu iter\uuuu
方法中无法执行。fib(30)
只是一个操作示例,它在循环中运行的时间不长,但足够长。CPU绑定的操作不是最好的主意,但是谢谢你的代码片段!
async def index(request, loop):
for i in range(20):
await loop.run_in_executor(None, not_so_long_operation)
async def index(request):
loop = request.app.loop
executor = request.app["executor"]
result = await loop.run_in_executor(executor, fib, 30)
return web.Response(text="%d" % result)
app = Application(...)
app["exector"] = ProcessPoolExector()
class arange:
def __init__(self, n):
self.n = n
self.i = 0
async def __aiter__(self):
return self
async def __anext__(self):
i = self.i
self.i += 1
if self.i <= self.n:
await asyncio.sleep(0) # insert yield point
return i
else:
raise StopAsyncIteration