Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用于ioloop的Python 3.5异步块_Python_Python 3.x_Async Await_Python Asyncio_Aiohttp - Fatal编程技术网

用于ioloop的Python 3.5异步块

用于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

我有一个带有两个处理程序的简单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__(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