Python 龙卷风路径到a";“基础”;处理者

Python 龙卷风路径到a";“基础”;处理者,python,routing,tornado,Python,Routing,Tornado,我使用tornado 4.5.2和路由实现。 我的服务器有两个版本的API,让它们调用base和fancy。因此,客户机可以同时使用这两种功能: GET /base/foo GET /base/baz GET /fancy/foo GET /fancy/baz 但是,一些花哨的处理程序可能无法实现;在这种情况下,应使用baseone 例如: application = web.Application([ (r"/base/foo", handlers.BaseFooHandler,

我使用tornado 4.5.2和路由实现。 我的服务器有两个版本的API,让它们调用
base
fancy
。因此,客户机可以同时使用这两种功能:

GET /base/foo
GET /base/baz

GET /fancy/foo
GET /fancy/baz
但是,一些花哨的处理程序可能无法实现;在这种情况下,应使用
base
one

例如:

application = web.Application([
    (r"/base/foo",  handlers.BaseFooHandler,  {"some": "settings"}),
    (r"/base/baz",  handlers.BaseBazHandler,  {"some": "settings"}),
    (r"/fancy/foo", handlers.FancyFooHandler, {"some": "settings"}),
])
当cilent请求GET/fancy/baz时,
BaseBazHandler
应该执行此任务


使用tornado路由如何实现这一点?

由于您使用装饰器注册路由,因此您可以创建一个自定义路由器,该路由器将响应所有未匹配/未注册的
/fancy/*
路由。要使其正常工作,您必须在最后注册路由器

这样,只有当尚未注册
/fancy/..
路由时,您的自定义路由器才会匹配。因此,这意味着自定义路由器类将需要执行以下操作:

  • 检查回退处理程序是否存在
  • 如果存在,将请求转发给它
  • 否则,返回404错误

  • 在继续之前,您必须创建一个自定义类来处理404请求。这是必要的,因为如果未找到处理程序,则这是返回404错误的最简单方法

    class Handle404(RequestHandler):
        def get(self):
            self.set_status(404)
            self.write('404 Not Found')
    

    好的,现在让我们编写自定义路由器:

    from tornado.routing import Router
    
    class MyRouter(Router):
        def __init__(self, app):
            self.app = app
    
        def find_handler(self, request, **kwargs):
            endpoint = request.path.split('/')[2] # last part of the path
    
            fallback_handler = 'Base%sHandler' % endpoint.title()
            # fallback_handler will look like this - 'BaseBazHandler'
    
            # now check if the handler exists in the current file
            try:
                handler = globals()[fallback_handler]
            except KeyError:
                handler = Handle404
    
            return self.app.get_handler_delegate(request, handler)
    
    from tornado.routing import PathMatches
    
    application.add_handlers(r'.*', # listen for all hosts
        [
            (PathMatches(r"/fancy/.*"), MyRouter(application)),
        ]
    )
    

    最后,添加所有其他路由后,您可以注册自定义路由器:

    from tornado.routing import Router
    
    class MyRouter(Router):
        def __init__(self, app):
            self.app = app
    
        def find_handler(self, request, **kwargs):
            endpoint = request.path.split('/')[2] # last part of the path
    
            fallback_handler = 'Base%sHandler' % endpoint.title()
            # fallback_handler will look like this - 'BaseBazHandler'
    
            # now check if the handler exists in the current file
            try:
                handler = globals()[fallback_handler]
            except KeyError:
                handler = Handle404
    
            return self.app.get_handler_delegate(request, handler)
    
    from tornado.routing import PathMatches
    
    application.add_handlers(r'.*', # listen for all hosts
        [
            (PathMatches(r"/fancy/.*"), MyRouter(application)),
        ]
    )
    


    我应该指出,
    MyRouter.find_handler
    ,只检查当前模块(文件)中的处理程序。如果需要,可以修改代码以搜索不同模块中的处理程序。

    确实如此,但我使用类装饰器自动添加处理程序,我不想编写一个黑客程序,如果没有相应的入口点,就添加额外的入口点handlers@SergeyBelash嗨,我已经更新了答案。看一看。