3

根据文档

传入中间件工厂的处理程序是下一个中间件工厂返回的处理程序。最后一个中间件工厂总是接收路由器本身选择的请求处理程序(通过 UrlDispatcher.resolve())。

我认为 UrlDispatcher.resolve() 将返回我分配的注册处理程序,所以我编写了这段代码。根据我的理解,当访问页面 127.0.0.1:9000 时,索引处理程序将用作 m1 的处理程序

import logging;
import asyncio
from aiohttp import web

logging.basicConfig(level=logging.INFO)

@asyncio.coroutine
def m1(app,handler):
    def log(request):
        r = yield from handler(request)
        logging.info(str(r))

@asyncio.coroutine
def index(request):
    return web.Response(body=b'<h1>Aswesome</h1>')

@asyncio.coroutine
def names(request):
    return web.Response(text='<h1>%s</h1>' % request.match_info['name'])

@asyncio.coroutine
def init(loop):
    app = web.Application(loop=loop, middlewares=[
        m1
    ])
    app.router.add_route('GET','/',index)
    app.router.add_route('GET','/{name:\w+}',names)
    srv = yield from loop.create_server(app.make_handler(),'127.0.0.1',9000)
    logging.info('server started at http://127.0.0.1:9000')
    return srv

loop = asyncio.get_event_loop()
loop.run_until_complete(init(loop))
loop.run_forever()

当我运行代码并在 127.0.0.1:9000 访问服务器时,我得到了

  File "/home/os/Documents/Python/web/lib/python3.5/site-packages/aiohttp/web.py", line 90, in handle_request
    resp = yield from handler(request)
TypeError: 'NoneType' object is not callable

在我看来,NoneType 作为处理程序传递到 m1 中间件

4

1 回答 1

3

log您的中间件不返回任何内容,但应该返回中间件处理程序。我在您的代码中添加了一行,它返回log.

@asyncio.coroutine
def m1(app,handler):
    def log(request):
        r = yield from handler(request)
        logging.info(str(r))
    return log  # changed

有关更多详细信息,请参阅有关中间件的文档。此外,值得研究 Python 3.5,它提供了async/await用于处理等待对象(即协程)的语法。的贡献者建议使用该语法aiohttp

请参阅官方PEP-492或Igor Davydenko 演讲中的幻灯片,其中介绍了新语法。

于 2016-05-09T13:48:11.233 回答