zoukankan      html  css  js  c++  java
  • tornado 学习笔记6 Application 源码分析

          Application 是Tornado重要的模块之一,主要是配置访问路由表及其他应用参数的设置。

          源代码位于虚拟运行环境文件夹下(我的是env),具体位置为env > lib>sit-packages>tornado>web.py。

         image

         注释大体意思:

            Application是由请求handlers集合组成,配置好application之后,直接作为参数传递给HTTPServer。

           这个类的构造函数包含URLSpec对象集合或者(正则表达式,request handler)元组集合。当服务器接收到请求时,我们会按顺序迭代循环集合,找到第一个与请求路径相匹配的正则表达式对应的配置项,然后实例化配置项中对应的hanlder对象。

           当然,tornado也支持虚拟主机,就是使用add_handles方法,使用主机正则表达式作为第一个参数。

    6.1 构造函数

         定义:

         def __init__(self, handlers=None, default_host="", transforms=None,
                  **settings):

        参数:

    • hanlders:为配置的URLSpec集合或者(正则表达式,hanlder)元组集合
    • default_host:默认的服务器名称。(暂时不知道干什么用的)
    • transforms:转换。是一个集合,内容转换处理器集合。用来对响应的内容进行转换处理,比如压缩处理。
    • settings:配置字典。

        主要处理过程:

              (1) 对静态文件的处理。

    #如果在设置中配置了static_path参数
    if self.settings.get("static_path"):
        #得到static_path参数值
        path = self.settings["static_path"]
        handlers = list(handlers or [])
        #得到static_url_prefix参数值,默认值为/static/
        static_url_prefix = settings.get("static_url_prefix",
                                         "/static/")
        #得到static_handler_class参数值,也就是静态文件处理类,默认值为StaticFileHandler
        static_handler_class = settings.get("static_handler_class",
                                            StaticFileHandler)
        #得到static_handler_args参数值,其他参数
        static_handler_args = settings.get("static_handler_args", {})
        static_handler_args['path'] = path
        #1将以static_url_prefix为前缀的路径访问以及根目录下的favicon.ico和robots.txt组成正则表达式,
        #2并将这些正则表达式关联到static_handler_class作为元组
        #3将这些元组一个一个插入到hanlders集合的最前面
        for pattern in [re.escape(static_url_prefix) + r"(.*)",
                        r"/(favicon.ico)", r"/(robots.txt)"]:
            handlers.insert(0, (pattern, static_handler_class,
                                static_handler_args))

              因为tornado请求的都是由hanlder来处理,由hanlder决定怎么返回响应。静态文件比如css文件、图片文件、以及其他word、excel、txt等文件,当游览器访问这些静态文件时,需进行区别业务hanlder的处理方式。

    举个例子:

              源码结构为:

    clip_image002

              源代码为:

    STATIC_ROOT = os.path.join(os.path.dirname(__file__), 'static').replace('\', '/')
    
    settings = {
    
    "static_path": STATIC_ROOT,
    
    "static_url_prefix": "/static/",
    
    'debug': True,
    
    }
    
    app = Application(handlers=[
    
    url(r"/", MainHanlder),
    
    url(r"/story/([0-9]+)", StoryHanlder, dict(db=db), name="story"),
    
    ], **settings)

                最后在游览器中访问style.css静态样式表文件。结果如下。

    clip_image004

               当然,可以根据你项目自身的结构配置static_path、static_url_prefix两个参数。

              (2) 对handlers的处理

                    if handlers:

                   self.add_handlers(".*$", handlers)

                   这里调用了add_handlers的方法。

              (3) 对设置参数情况的处理

    if self.settings.get('debug'):
    
    self.settings.setdefault('autoreload', True)
    
    self.settings.setdefault('compiled_template_cache', False)
    
    self.settings.setdefault('static_hash_cache', False)
    
    self.settings.setdefault('serve_traceback', True)
    
    # Automatically reload modified modules
    
    if self.settings.get('autoreload'):
    
    from tornado import autoreload
    
    autoreload.start()

    6.2 设置参数说明

    Application可以设置的参数包括3种类型,分别是一般参数、授权和安全设置参数、模板参数、静态文件配置参数。

        一般参数:

    • l autoreload: 如果是True,当任何源文件改变时,服务器进程将会重新启动。这个选项只有在3.2版本有,以前这个功能被debug选项控制。
    • l debug: 设置成调试模式。debug = True 等同于 autoreload=True,compiled_template=False,static_hash_cache=False,serve_traceback=True.
    • l default_handler_class 以及default_handler_args: 如果没有找到相匹配的handler,会使用这个默认的handler.s使用这个可以自定义404页面。
    • l compresss_response: 如果设置成True.文本格式返回的响应会被压缩。在tornado 4.0版本才有这功能。
    • l gzip : 从4.0版本后过时,被compresss_response替代
    • l log_function :在每个请求响应之后,这个函数会被调用,用来记录结果。默认实现是写入到logging模块的跟日志记录器中。这个可以被自定义。
    • l serve_traceback: 如果设置成true. 默认的错误页面会包含错误跟踪。这个选项在3.2版本新增的。之前的版本通过设置debug=true来实现功能。
    • l ui_modules 和ui_methods:设置对ui 模板的 UIModule 或者UIMethods的映射。

        授权和安全设置参数:

    • l cookie_secret: 被RequestHandler.get_secure_cookie 和set_secure_cookie使用,用来签发cookies;
    • l login_url:如果用户没有登录,使用了authenticated装饰器的请求处理都会重定向到这个url.可以重写RequestHanlder.get_login_url进行进一步的自定义。
    • l xsrf_cookies: 如果设置成True,跨站(Cross-site)保护会被启动。

        模板参数:

    • l autoscape: 为模板控制自动转义。可以设置成None来禁用转义,或者设置成一个函数名称,这样所有的输出都会被传递。默认值为 xhtml_escape.可以通过 {% autoescape %}指令在每一个模板上进行改变;
    • l compiled_template_cache: 默认设置为True。如果设置成False,针对每个请求,每个模板都会重新编译。这个选项在3.2版本中新增,以前版本都是通过设置debug选项来实现。
    • l template_path :包含template文件的文件夹目录。可以重写 RequestHandler.get_template_path来进一步自定义。
    • l template_loader: 给tornado.template.BaseLoader设置一个实例,用来自定义模板的加载。如果这个选项设置了,那么template_path 以及 autoescape 这两个选项会被忽视。这个通过重写RequestHandler.create_template_loader来进一步实现自定义。

        静态文件设置:

    • l static_hash_cache: 默认值为True.如果为False,针对每一个请求,静态url将会被重新计算。这个选项是在3.2版本新增的。以前这个功能只能通过debug设置来控制。
    • l static_path: 静态文件所在目录。
    • l static_url_prefix:静态文件访问得url前缀。默认为:“/static”
    • l static_handler_class,static_handler_args: 可以使用自定义的静态文件处理器去替代默认的tornado.web.StaticFileHandler。static_handler_args,如果设置了,必须为一个字典,而且会被传递到handler的initialize方法作为参数。

    6.3 add_handlers方法

    在构造函数中处理中,有一个很重要的过程,就是对配置的handlers进行处理。就是add_hanlders方法。

    这个方法的是将给定的hanlders追加到我们的hanlder列表中。

    • 方法定义:def add_handlers(self, host_pattern, host_handlers):
    • 参数:

                 host_pattern: 虚拟主机匹配的正则表达式。Application默认设置为””

                 host_handlers :要添加的handlers。

    • 源码分析:
    if not host_pattern.endswith("$"):    host_pattern += "$"
    handlers = []
    # The handlers with the wildcard host_pattern are a special
    # case - they're added in the constructor but should have lower
    # precedence than the more-precise handlers added later.
    # If a wildcard handler group exists, it should always be last
    # in the list, so insert new groups just before it.
    if self.handlers and self.handlers[-1][0].pattern == '.*$':
        self.handlers.insert(-1, (re.compile(host_pattern), handlers))
    else:
        self.handlers.append((re.compile(host_pattern), handlers))
    
    for spec in host_handlers:
        if isinstance(spec, (tuple, list)):
            assert len(spec) in (2, 3, 4)
            spec = URLSpec(*spec)
        handlers.append(spec)
        if spec.name:
            if spec.name in self.named_handlers:
                app_log.warning(
                    "Multiple handlers named %s; replacing previous value",
                    spec.name)
            self.named_handlers[spec.name] = spec

            方法主要逻辑是将handlers添加至Application的handlers属性中,但是添加的hanlder首先必须转换成URLSpec类型。如果hanlder配置了命名参数,检验名称的唯一性,并如果存在重复,将进行覆盖,并记录在日志中。

            通过 if isinstance(spec, (tuple, list)) 源码可以看出,hanlders的配置类型可以有两种类型,一种是元组集合,一种是列表,而如果是列表的话,那么列表中的项是URLSpec类型。而且每一handler是可以命名的。举个例子:Application的创建可以以下两个方式:

            方式一:hanlders用URLSpec对象列表传递,并且可以命名。

    app = Application(handlers=[
        url(r"/", MainHanlder),
        url(r"/story/([0-9]+)", StoryHanlder, dict(db=db), name="story"),
    ], **settings)

            方式二:hanlders用元组集合传递

    app = Application(handlers=[
        url(r"/", MainHanlder),
        url(r"/story/([0-9]+)", StoryHanlder, dict(db=db), name="story"),
    ], **settings)
  • 相关阅读:
    【01】markdown语法
    H5系列之地理位置(必知必会)
    【07】像使用命令行一样使用 GitHub URL
    【11】把 GitHub 当 CMS 用
    【01】在 issue 中创建 list
    【06】GitHub WiKi
    【05】project board
    7.10-11 visudo、sudo
    7.7-9 chage、chpasswd、su
    7.1 useradd:创建用户
  • 原文地址:https://www.cnblogs.com/liaofeifight/p/4930398.html
Copyright © 2011-2022 走看看