tornado入门笔记

隔壁老王 等级 761 0 0
标签: tornadoPython

官方文档

https://www.tornadoweb.org/en/stable/

简单使用

# !/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Wjy
import tornado.ioloop  # 启动
import tornado.web  # 请求对象
import tornado.template  # 模板


class Index(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.write("首页123")


def make_app():
    return tornado.web.Application([
        (r"/index", Index)
    ])  # debug=True会自动加载改变的py文件,不过会导致自动挂载后台


if __name__ == '__main__':
    app = make_app()
    app.listen(8000)
    tornado.ioloop.IOLoop.current().start()

单进程

# -*- coding: utf-8 -*-
# Author: Wjy
import tornado.ioloop  # 启动
import tornado.web  # 请求对象
import tornado.template  # 模板
import tornado.autoreload
import tornado.netutil
import tornado.process
from tornado.httpserver import HTTPServer


class Index(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.write("首页123")


if __name__ == '__main__':
    tornado.autoreload = True  # debug模式
    app = tornado.web.Application([
            (r"/index", Index)
        ])  # debug=True会自动加载改变的py文件,不过会导致自动挂载后台
    http = tornado.httpserver.HTTPServer(app)
    http.listen(8000)
    tornado.ioloop.IOLoop.current().start()

多进程

# !/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Wjy
import tornado.ioloop  # 启动
import tornado.web  # 请求对象
import tornado.template  # 模板
import tornado.httpserver


class MainHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        # 获取get请求一个参数
        print(self.get_argument("a"))
        # 获取get请求中参数列表
        print(self.get_arguments("b"))
        self.write("get 请求")

    def post(self, *args, **kwargs):
        # 获取表单数据
        # print(self.get_body_argument("name"))
        # 获取表单列表数据
        # print(self.get_body_arguments("body"))
        # 获取body原始数据
        print(self.request.body)
        # 获取请求头
        print(self.request.headers)
        self.write("post 请求")

    def head(self, *args, **kwargs):
        self.write("head 请求")

    def delete(self, *args, **kwargs):
        self.write("delete 请求")

    def patch(self, *args, **kwargs):
        self.write("patch 请求")

    def put(self, *args, **kwargs):
        self.write("put 请求")

    def options(self, *args, **kwargs):
        self.write("options 请求")


    def prepare(self):
        '''
        前置钩子
        :return:
        '''
        # self.write("prepare 前置钩子")

    def on_finish(self):
        '''
        后置钩子
        :return:
        '''
        # self.write("on_finish 后置钩子")

    def initialize(self):
        '''
        钩子
        :return:
        '''
        # self.write("initialize 每次都会被调用的钩子")


class Index(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.write("首页123")


if __name__ == '__main__':
    make_app = tornado.web.Application([
        (r"/", MainHandler),
        (r"/index", Index)
    ])
    app = tornado.httpserver.HTTPServer(make_app)  # 标准写法
    app.bind(8000)
    app.start(1)  # 多进程控制
    tornado.ioloop.IOLoop.current().start()

说明:

http_server.bind(port)方法是将服务器绑定到指定端口。

http_server.start(num_processes=1)方法指定开启几个进程,参数num_processes默认值为1,即默认仅开启一个进程;如果num_processes为None或者<=0,则自动根据机器硬件的cpu核芯数创建同等数目的子进程;如果num_processes>0,则创建num_processes个子进程。

1.关于app.listen()

app.listen()这个方法只能在单进程模式中使用。

对于app.listen()与手动创建HTTPServer实例

http_server = tornado.httpserver.HTTPServer(app) 
http_server.listen(8000)

2.关于多进程

虽然tornado给我们提供了一次开启多个进程的方法,但是由于:

  • 每个子进程都会从父进程中复制一份IOLoop实例,如过在创建子进程前我们的代码动了IOLoop实例,那么会影响到每一个子进程,势必会干扰到子进程IOLoop的工作;

  • 所有进程是由一个命令一次开启的,也就无法做到在不停服务的情况下更新代码;

  • 所有进程共享同一个端口,想要分别单独监控每一个进程就很困难。

不建议使用这种多进程的方式,而是手动开启多个进程,并且绑定不同的端口。

Application中settings可以设置的参数

#设置templates路径:
template_path = os.path.join(os.path.dirname(__file__), "templates")

#设置静态文件解析路径:
static_path = os.path.join(os.path.dirname(__file__), "static"),

#设置防跨站请求攻击:
xsrf_cookies = True,
# {% module xsrf_form_html() %} html中加入该参数
#默认为False,即不可防御。

#设置登陆路径,未登陆用户在操作时跳转会用到这个参数:
login_url = "/login-do",
#默认为@tornado.web.authenticated

#设置调试模式:
debug = True,
#默认为False,即不是调试模式。

#设置cookie密钥:
cookie_secret = "dskfhisdjklagkfdklag;lkjasdklgjkldsjaklgjkldsfksdklf"
#默认为字符串"secure cookies"

#设置是否自动编码:在2.0以上需要设置此项来兼容您之前的APP
autoescape = None,
#不设置默认为自动编码。

#设置template_loader,可以从独立的路径中导入template:
template_loader=utils.ZipLoader,
#其中utils为自己定义的模块,ZipLoader是tornado.template.BaseLoader的子类。

#设置gzip压缩:
gzip=True

#设置静态路径头部:
static_url_prefix = "/mystatic/",
#默认是"/static/"

#设置静态文件处理类:
static_handler_class = MyStaticFileHandler,
#默认是tornado.web.StaticFileHandler

#设置静态文件的参数:
static_handler_args = { "key1":"value1", "key2":"value2"  }
#默认为空字典。

#设置日志处理函数
log_function = your_fun,
# 日志处理函数your_fun,按照自己的意图记录日志。

define和options

# !/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Wjy
import tornado.ioloop  # 启动
import tornado.web  # 请求对象
import tornado.httpserver
from tornado.options import options, define

# 定义全局变量,options.出定义的这个变量
define("port", default=8000, help="监听的端口")


class Index(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        self.write("首页123")


if __name__ == '__main__':
    tornado.autoreload = True  # debug模式
    app = tornado.web.Application([
        (r"/index", Index)
    ])
    http = tornado.httpserver.HTTPServer(app)
    http.listen(options.port)
    tornado.ioloop.IOLoop.current().start()

模板基础

# !/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Wjy
import tornado.ioloop  # 启动
import tornado.web  # 请求对象
import tornado.httpserver  # http服务
import tornado.template  # 模板的使用
import tornado.autoreload
from tornado.options import options, define

# 定义全局变量,options.出定义的这个变量
define("port", default=8000, help="监听的端口")


class Index(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        # 构建模板
        t = tornado.template.Template("<html>{{ myvalue }}</html>")
        # 填充模板参数
        self.write(t.generate(myvalue="hello1"))


if __name__ == '__main__':

    app = tornado.web.Application([
        (r"/index", Index)
    ])
    http = tornado.httpserver.HTTPServer(app)
    http.listen(options.port)

    instance = tornado.ioloop.IOLoop.instance().start()

模板语法参考

模板表达式由双花括号包围:。内容可以是任何python表达式,它将根据当前的autoescape设置进行转义并插入到输出中。其他模板指令使用。{{ ... }}{% %}

要注释掉一个部分,使其从输出中省略,请用它包围。{# ... #}

这些标签可以被转义为{{!,{%!以及{#! 如果需要包括文字{{,{%或{#在输出中。

{% apply *function* %}...{% end %}
将函数应用于apply 和之间的所有模板代码的输出end:

{% apply linkify %}{{name}} said: {{message}}{% end %}
请注意,作为实现细节,应用块实现为嵌套函数,因此可能与通过设置的变量或使用或 在循环内进行奇怪的交互。{% set %}{% break %}{% continue %}

{% autoescape *function* %}
设置当前文件的自动调用模式。这不会影响其他文件,甚至是那些引用的文件。请注意,也可以在 或者全局配置自动加载:{% include %}ApplicationLoader

{% autoescape xhtml_escape %}
{% autoescape None %}
{% block *name* %}...{% end %}
表示用于的可命名的可替换块。父模板中的块将替换为子模板中同名块的内容:{% extends %}
<!-- base.html -->
<title>{% block title %}Default title{% end %}</title>

<!-- mypage.html -->
{% extends "base.html" %}
{% block title %}My page title{% end %}
{% comment ... %}
将从模板输出中删除的注释。请注意,没有标签; 评论从单词 到结束标记。{% end %}comment%}
{% extends *filename* %}
从另一个模板继承。使用的模板extends应包含一个或多个block标记,以替换父模板中的内容。子block 标记中未包含在标记中的任何内容都将被忽略。有关示例,请参阅标记。{% block %}
{% for *var* in *expr* %}...{% end %}
与python for语句相同。 并且 可以在循环内使用。{% break %}{% continue %}
{% from *x* import *y* %}
与python import语句相同。
{% if *condition* %}...{% elif *condition* %}...{% else %}...{% end %}
条件语句 - 输出条件为真的第一部分。(这些elif和else部分是可选的)
{% import *module* %}
与python import语句相同。
{% include *filename* %}
包含另一个模板文件。包含的文件可以看到所有局部变量,就好像它被直接复制到include 指令点(该指令是一个例外)。或者,可以用于包括具有隔离命名空间的另一个模板。{% autoescape %}{% module Template(filename, **kwargs) %}
{% module *expr* %}
呈现一个UIModule。该输出UIModule未转义:

{% module Template("foo.html", arg=42) %}
UIModules是tornado.web.RequestHandler 类的一个特性(特别是它的render方法),当模板系统在其他环境中单独使用时,它将不起作用。

{% raw *expr* %}
输出给定表达式的结果而不进行自动转换。
{% set *x* = *y* %}
设置局部变量。
{% try %}...{% except %}...{% else %}...{% finally %}...{% end %}
与python try语句相同。
{% while *condition* %}... {% end %}
与python while语句相同。 并且 可以在循环内使用。{% break %}{% continue %}
{% whitespace *mode* %}
为当前文件的其余部分设置空白模式(或直到下一个指令)。请参阅 可用选项。Tornado 4.3中的新功能。{% whitespace %}filter_whitespace

类引用

class tornado.template.Template(template_string,name =“<string>”,loader = None,compress_whitespace = None,autoescape =“xhtml_escape”,whitespace = None )[source]
编译模板。

我们从给定的template_string编译成Python。您可以使用generate()从变量生成模板。

构造一个模板。

参数:

template_string(str) - 模板文件的内容。
name(str) - 加载模板的文件名(用于错误消息)。
loader(tornado.template.BaseLoader) - BaseLoader负责此模板,用于解析和指令。{% include %}{% extend %}
compress_whitespace(bool) - 自Tornado 4.3以来已弃用。相当于whitespace="single"if和 whitespace="all"false。
autoescape(str) - 模板命名空间中函数的名称,或None默认情况下禁用转义。
whitespace(str) - 指定空白处理的字符串; 看看filter_whitespace选项。
版本4.3更改:添加whitespace参数; 已弃用compress_whitespace。

generate(** kwargs )[来源]
使用给定的参数生成此模板。

class tornado.template.BaseLoader(autoescape ='xhtml_escape',namespace = None,whitespace = None )[来源]
模板加载器的基类。

您必须使用模板加载器来使用和等模板结构 。加载程序在第一次加载后缓存所有模板。{% extends %}{% include %}
构造模板加载器。

参数:

autoescape(str) - 模板命名空间中函数的名称,例如“xhtml_escape”,或None默认情况下禁用自动转义。
namespace(dict) - 要添加到默认模板名称空间的字典,或None。
whitespace(str) - 一个字符串,指定模板中空格的默认行为; 看看filter_whitespace选项。对于以“.html”和“.js”结尾的文件,默认为“single”,对于其他文件,默认为“all”。
版本4.3中已更改:已添加whitespace参数。

reset()[来源]
重置已编译模板的缓存。

resolve_path(name,parent_path = None )[来源]
将可能相对路径转换为绝对路径(在内部使用)。

load(name,parent_path = None )[来源]
加载模板。

class tornado.template.Loader(root_directory,** kwargs )[来源]
从单个根目录加载的模板加载器。

class tornado.template.DictLoader(dict,** kwargs )[来源]
从字典加载的模板加载器。

异常tornado.template.ParseError(消息,文件名=无,行号= 0 )[来源]
引发模板语法错误。

ParseError实例具有指示错误位置的属性filename和lineno属性。

版本4.3中已更改:已添加filename和lineno属性。

tornado.template.filter_whitespace(模式,文字)[来源]
text根据变换空格mode。

可用的模式是:

all:返回所有未经修改的空格。
single:使用单个空格字符折叠连续的空格,保留换行符。
oneline:将所有空白行都折叠到一个空格字符中,删除过程中的所有换行符。

模板应用py文件

# !/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Wjy
import tornado.ioloop  # 启动
import tornado.web  # 请求对象
import tornado.httpserver  # http服务
import tornado.template  # 模板的使用
import tornado.autoreload
from tornado.options import options, define

# 定义全局变量,options.出定义的这个变量
define("port", default=8000, help="监听的端口")


class Index(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        students = [dict(name='david'), dict(name='jack')]

        # 原始写法
        # loader = tornado.template.Loader("templates")
        # t = loader.load("base.html")
        # self.write(t.generate(students=students))

        self.render("test.html", students=students)


if __name__ == '__main__':

    app = tornado.web.Application([
        (r"/index", Index)
    ],
    template_path="./templates"  # 与render配合使用
    )
    http = tornado.httpserver.HTTPServer(app)
    http.listen(options.port)

    instance = tornado.ioloop.IOLoop.current().start()

base.html

<html>
  <head>
    <title>{% block title %}Default title{% end %}</title>
  </head>
  <body>
    <ul>
      {% for student in students %}
        {% block student %}
          <li>{{ escape(student['name']) }}</li>
        {% end %}
      {% end %}
    </ul>
  </body>
</html>

test.html

{% extends "base.html" %}

{% block title %}A bolder title{% end %}

{% block student %}
  <li><span style="bold">{{ escape(student['name']) }}</span></li>
{% end %}

路由的实现

tornado.routing- 基本路由实现

Tornado使用Router 类实现将HTTP请求路由到适当的处理程序。的tornado.web.Application类是一个 Router实现,并且可以直接使用,或在该模块中的类可以用于额外的灵活性。的RuleRouter 类可以匹配比多个准则Application,或Router 接口可以被继承为最大定制。

Router接口扩展HTTPServerConnectionDelegate 以提供额外的路由功能。这也意味着,任何 Router实现可以直接用作request_callback 用于HTTPServer构造函数。

Router子类必须实现一个find_handler方法来提供一个合适的HTTPMessageDelegate实例来处理请求:

class CustomRouter(Router):
    def find_handler(self, request, **kwargs):
        # some routing logic providing a suitable HTTPMessageDelegate instance
        return MessageDelegate(request.connection)

class MessageDelegate(HTTPMessageDelegate):
    def __init__(self, connection):
        self.connection = connection

    def finish(self):
        self.connection.write_headers(
            ResponseStartLine("HTTP/1.1", 200, "OK"),
            HTTPHeaders({"Content-Length": "2"}),
            b"OK")
        self.connection.finish()

router = CustomRouter()
server = HTTPServer(router)

实现的主要责任Router是提供从请求到HTTPMessageDelegate将处理此请求的实例的映射。在上面的示例中,我们可以看到即使没有实例化路由也可以进行路由Application。

为了路由到RequestHandler实现,我们需要一个 Application实例。get_handler_delegate 提供了一种HTTPMessageDelegate 为给定请求创建的便捷方式RequestHandler。

以下是我们如何RequestHandler通过HTTP方法路由到子类的简单示例 :

resources = {}

class GetResource(RequestHandler):
    def get(self, path):
        if path not in resources:
            raise HTTPError(404)

        self.finish(resources[path])

class PostResource(RequestHandler):
    def post(self, path):
        resources[path] = self.request.body

class HTTPMethodRouter(Router):
    def __init__(self, app):
        self.app = app

    def find_handler(self, request, **kwargs):
        handler = GetResource if request.method == "GET" else PostResource
        return self.app.get_handler_delegate(request, handler, path_args=[request.path])

router = HTTPMethodRouter(Application())
server = HTTPServer(router)

ReversibleRouterinterface添加了区分路由的功能,并使用路由名称和其他参数将它们反转到原始URL。Application本身就是一个ReversibleRouter类的实现。

RuleRouter并且ReversibleRuleRouter是Router和ReversibleRouter接口的实现, 并且可以用于创建基于规则的路由配置。

规则是Rule类的实例。它们包含a Matcher,它提供用于确定规则是否与特定请求和目标匹配的逻辑,可以是以下之一。

一个例子HTTPServerConnectionDelegate:

router = RuleRouter([
    Rule(PathMatches("/handler"), ConnectionDelegate()),
    # ... more rules
])

class ConnectionDelegate(HTTPServerConnectionDelegate):
    def start_request(self, server_conn, request_conn):
        return MessageDelegate(request_conn)

可调用接受单个HTTPServerRequest类型的参数:

router = RuleRouter([
    Rule(PathMatches("/callable"), request_callable)
])

def request_callable(request):
    request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
    request.finish()

另一个Router例子:

router = RuleRouter([
    Rule(PathMatches("/router.*"), CustomRouter())
])

当然是嵌套RuleRouter或Application允许的:

router = RuleRouter([
    Rule(HostMatches("example.com"), RuleRouter([
        Rule(PathMatches("/app1/.*"), Application([(r"/app1/handler", Handler)]))),
    ]))
])

server = HTTPServer(router)

在下面的示例中RuleRouter用于在应用程序之间进行路由:

app1 = Application([
    (r"/app1/handler", Handler1),
    # other handlers ...
])

app2 = Application([
    (r"/app2/handler", Handler2),
    # other handlers ...
])

router = RuleRouter([
    Rule(PathMatches("/app1.*"), app1),
    Rule(PathMatches("/app2.*"), app2)
])

server = HTTPServer(router)

有关应用程序级路由的更多信息,请参阅docs Application。

4.5版中的新功能。

class tornado.routing.Router[source]

抽象路由器接口。

find_handler(请求,** kwargs )[来源]

必须实现以返回HTTPMessageDelegate 可以为请求提供服务的适当实例。路由实现可以传递额外的kwargs来扩展路由逻辑。

参数:

request(httputil.HTTPServerRequest) - 当前的HTTP请求。
kwargs - 路由实现传递的其他关键字参数。

返回:

其实例HTTPMessageDelegate将用于处理请求。
class tornado.routing.ReversibleRouter[source]

路由器的抽象路由器接口,可以处理命名路由并支持将它们反转为原始URL。

reverse_url(name,* args )[来源]

返回给定路由名称和参数的url字符串,或者None如果找不到匹配项。

参数:

name(str) - 路由名称。
args - url参数。
返回:    
给定路由名称(或None)的参数化url字符串。
class tornado.routing.RuleRouter(rules = None )[来源]

基于规则的路由器实现。

从有序的规则列表构造路由器:

RuleRouter([
    Rule(PathMatches("/handler"), Target),
    # ... more rules
])

您还可以省略显式Rule构造函数并使用参数元组:

RuleRouter([
    (PathMatches("/handler"), Target),
])

PathMatches 是默认匹配器,因此上面的示例可以简化:

RuleRouter([
    ("/handler", Target),
])

在上面的示例中,Target可以是嵌套Router实例,实例 HTTPServerConnectionDelegate或旧式可调用,接受请求参数。

参数:

  • rules - 构造函数参数的Rule实例或元组列表Rule。
add_rules(规则)[来源]
  • 将新规则附加到路由器。

参数:

  • rules - Rule实例列表(或参数元组,传递给Rule构造函数)。
process_rule(规则)[来源]

重写此方法以对每个规则进行其他预处理。

参数:

  • rule(Rule) - 要处理的规则。

返回:

  • 相同或修改过的Rule实例。
  • get_target_delegate(目标,请求,** target_params )[来源]
  • 返回HTTPMessageDelegateRule的目标实例。此方法由find_handler并且可以扩展以提供其他目标类型。

参数:

  • target - 规则的目标。
  • request(httputil.HTTPServerRequest) - 当前请求。
  • target_params - 可用于HTTPMessageDelegate创建的其他参数。
  • class tornado.routing.ReversibleRuleRouter(rules = None )[来源]
  • 实现reverse_url方法的基于规则的路由器。

添加到此路由器的每个规则可以具有name可用于重建原始uri 的属性。实际的重建发生在规则的匹配器中(参见参考资料Matcher.reverse)。

class tornado.routing.Rule(matcher,target,target_kwargs = None,name = None )[来源]

路由规则。

构造一个Rule实例。

参数:

  • matcher(Matcher) - Matcher用于确定规则是否应被视为特定请求匹配的实例。
  • target - 规则的目标(通常是一个RequestHandler或 HTTPServerConnectionDelegate子类,甚至是嵌套的Router,具体取决于路由实现)。
  • target_kwargs(dict) - 在目标实例化时可能有用的参数的dict(例如,status_code 对于RequestHandler子类)。他们最终进入 target_params['target_kwargs']了RuleRouter.get_target_delegate 方法。
  • name(str) - 可用于在ReversibleRouter.reverse_url实现中查找它的规则的名称。
class tornado.routing.Matcher[source]

表示请求功能的匹配器。

match(要求)[来源]

根据请求匹配当前实例。

参数:

  • request(httputil.HTTPServerRequest) - 当前的HTTP请求

返回:

  • 的参数一个字典被传递给目标的处理程序(例如,handler_kwargs,path_args,path_kwargs 可以传递适当RequestHandler实例化)。空dict是一个有效(和常见)返回值,用于指示不使用参数传递功能时的匹配。 None必须返回以表明没有匹配。
reverse(* args )[来源]

从matcher实例和其他参数重构完整的url。

class tornado.routing.AnyMatches[source]

匹配任何请求。

class tornado.routing.HostMatches(host_pattern )[source]

匹配来自host_patternregex 指定的主机的请求。

class tornado.routing.DefaultHostMatches(application,host_pattern )[source]

匹配来自主机的请求,该请求等于应用程序的default_host。如果X-Real-Ip标题存在,则始终不返回匹配项。

class tornado.routing.PathMatches(path_pattern )[source]

使用path_patternregex 指定的路径匹配请求。

class tornado.routing.URLSpec(pattern,handler,kwargs = None,name = None )[source]

指定URL和处理程序之间的映射。

参数:

  • pattern:正则表达式匹配。正则表达式中的任何捕获组都将作为参数传递给处理程序的get / post / etc方法(如果已命名,则按关键字传递,如果未命名,则按位置传递。命名和未命名的捕获组可能不会在同一规则中混合)。
  • handler:RequestHandler要调用的子类。
  • kwargs (可选):要传递给处理程序构造函数的其他参数的字典。
  • name(可选):此处理程序的名称。使用者 reverse_url。

tornado.escape- 转义和字符串操作

HTML,JSON,URL等的转义/转义方法。

还包括一些随时间推移的其他杂项字符串操作函数。

转义函数
tornado.escape.xhtml_escape(值)[来源]
转义字符串,使其在HTML或XML中有效。

转义字符<,>,",',和&。在属性值中使用时,转义字符串必须用引号括起来。

版本3.2中已更改:将单引号添加到转义字符列表中。
tornado.escape.xhtml_unescape(值)[来源]
取消转义XML转义字符串。
tornado.escape.url_escape(value,plus = True )[来源]
返回给定值的URL编码版本。

如果plus为true(默认值),则空格将表示为“+”而不是“%20”。这适用于查询字符串,但不适用于URL的路径组件。请注意,此默认值与Python的urllib模块相反。

新的3.1版:该plus参数
tornado.escape.url_unescape(value,encoding ='utf-8',plus = True )[来源]
从URL解码给定值。

参数可以是字节或unicode字符串。

如果encoding是None,则结果将是字节字符串。否则,结果是指定编码中的unicode字符串。

如果plus为真(默认值),加号将被解释为空格(文字加号必须表示为“%2B”)。这适用于查询字符串和表单编码值,但不适用于URL的路径组件。请注意,此默认值与Python的urllib模块相反。

新的3.1版:该plus参数
tornado.escape.json_encode(值)[来源]
JSON编码给定的Python对象。
tornado.escape.json_decode(值)[来源]
返回给定JSON字符串的Python对象。
字节/ unicode转换
这些函数在Tornado中广泛使用,但大多数应用程序不应该直接使用它们。请注意,这些函数的大部分复杂性来自于Tornado支持Python 2和Python 3的事实。
tornado.escape.utf8(值)[来源]
将字符串参数转换为字节字符串。

如果参数已经是字节字符串或None,则返回不变。否则它必须是unicode字符串并编码为utf8。
tornado.escape.to_unicode(值)[来源]
将字符串参数转换为unicode字符串。

如果参数已经是unicode字符串或None,则返回不变。否则它必须是字节字符串并解码为utf8。

tornado.escape.native_str()
将字节或unicode字符串转换为类型str。相当于 utf8Python 2和to_unicodePython 3。
tornado.escape.to_basestring(值)[来源]
将字符串参数转换为basestring的子类。

在python2中,byte和unicode字符串大多可以互换,因此处理用户提供的参数和ascii字符串常量的函数可以使用任何一个并且应该返回用户提供的类型。在python3中,这两种类型不可互换,因此需要此方法将字节字符串转换为unicode。
tornado.escape.recursive_unicode(obj )[来源]
走一个简单的数据结构,将字节串转换为unicode。

支持列表,元组和词典。
杂项功能
tornado.escape.linkify(text,shorten = False,extra_params ='',require_protocol = False,allowed_protocols = ['http','https'] )[source]
使用链接将纯文本转换为HTML。

例如:会回来 linkify("Hello http://tornadoweb.org!")Hello <a href="http://tornadoweb.org">http://tornadoweb.org</a>!

参数:

- shorten:长网将缩短显示。

- extra_params:要包含在链接标记中的额外文本,或者将链接作为参数并返回额外文本的可调用文件,例如,或:linkify(text, extra_params='rel="nofollow" class="external"')

def extra_params_cb(url):
    if url.startswith("http://example.com"):
        return 'class="internal"'
    else:
        return 'class="external" rel="nofollow"'
linkify(text, extra_params=extra_params_cb)
- require_protocol:仅链接包含协议的URL。如果这是假的,那么诸如www.facebook.com之类的网址也将被链接。

- permitted_protocols:列出(或设置)应该链接的协议,例如。包含诸如的协议是非常不安全的 。linkify(text, permitted_protocols=["http", "ftp", "mailto"])javascript
tornado.escape.squeeze(值)[来源]
用单个空格替换所有空白字符序列。

tornado.locale- 国际化支持

生成本地化字符串的翻译方法。

要加载区域设置并生成已翻译的字符串:

user_locale = tornado.locale.get("es_LA")
print(user_locale.translate("Sign out"))

tornado.locale.get()返回最接近的匹配区域设置,不一定是您请求的特定区域设置。您可以使用其他参数支持复数translate(),例如:

people = [...]
message = user_locale.translate(
    "%(list)s is online", "%(list)s are online", len(people))
print(message % {"list": user_locale.list(people)})

如果是,则选择第一个字符串,否则选择第二个字符串。len(people) == 1

应用程序应调用其中一个load_translations(使用简单的CSV格式)或load_gettext_translations(使用.mo支持的格式gettext和相关工具)。如果两个方法都没有被调用,则该Locale.translate方法将只返回原始字符串。

tornado.locale.get(* locale_codes )[来源]
返回给定区域设置代码的最接近匹配项。

我们按顺序迭代所有给定的区域设置代码。如果我们对代码有一个紧密或松散的匹配(例如,“en”代表“en_US”),我们返回语言环境。否则,我们移动到列表中的下一个代码。

默认情况下,en_US如果找不到任何指定语言环境的翻译,则返回。您可以使用更改默认语言环境 set_default_locale()。
tornado.locale.set_default_locale(代码)[来源]
设置默认语言环境。

假定默认语言环境是用于系统中所有字符串的语言。从磁盘加载的转换是从默认语言环境到目标语言环境的映射。因此,您无需为默认语言环境创建转换文件。
tornado.locale.load_translations(目录,编码=无)[来源]

从目录中的CSV文件加载翻译。

翻译是具有可选的Python风格的命名占位符(例如)及其相关翻译的字符串。My name is %(name)s

该目录应具有表单的翻译文件LOCALE.csv,例如es_GT.csv。CSV文件应包含两列或三列:字符串,翻译和可选的复数指示符。多个指标应该是“复数”或“单数”之一。给定的字符串可以具有单数和复数形式。例如,取决于%(name)s是一个名称还是名称列表,可以具有不同的动词共轭。CSV文件中应该有两行用于该字符串,一行具有复数指示符“单数”,一行具有“复数”。对于没有动词在翻译时会改变的字符串,只需使用“unknown”或空字符串(或者根本不包括该列)。%(name)s liked this

使用csv默认“excel”方言中的模块读取文件。在这种格式中,逗号后面不应有空格。

如果没有encoding给出参数,如果文件包含字节顺序标记(BOM),将自动检测编码(在UTF-8和UTF-16中),如果没有BOM,则默认为UTF-8。

翻译示例es_LA.csv:

"I love you","Te amo"
"%(name)s liked this","A %(name)s les gustó esto","plural"
"%(name)s liked this","A %(name)s le gustó esto","singular"

版本4.3中已更改:已添加encoding参数。添加了对基于BOM的编码检测,UTF-16和带有BOM的UTF-8的支持。

tornado.locale.load_gettext_translations(目录,域名)[来源]

加载来自gettext语言环境树的翻译

区域设置树类似于系统/usr/share/locale,如:

{directory}/{lang}/LC_MESSAGES/{domain}.mo

翻译您的应用需要三个步骤:

  1. 生成POT翻译文件:

    xgettext --language=Python --keyword=_:1,2 -d mydomain file1.py file2.html etc

  2. 合并现有的POT文件:

    msgmerge old.po mydomain.po > new.po

  3. 编译:

    msgfmt mydomain.po -o {directory}/pt_BR/LC_MESSAGES/mydomain.mo

    tornado.locale.get_supported_locales()[来源]

    返回所有受支持的区域设置代码的列表。

class tornado.locale.Locale(代码,翻译)[来源]

表示区域设置的对象。

调用load_translationsor 之一后load_gettext_translations,调用get或get_closest获取Locale对象。

classmethod get_closest(* locale_codes )[source]

返回给定区域设置代码的最接近匹配项。

classmethod get(code )[source]

返回给定语言环境代码的Locale。

如果不支持,我们会引发异常。

translate(message,plural_message = None,count = None )[来源]

返回此语言环境的给定消息的翻译。

如果plural_message给出,您还必须提供 count。我们返回plural_message时,我们返回给定消息的单数形式 。count != 1count == 1

format_date(日期,gmt_offset = 0,相对=真,较短=假,full_format =假)[源]

格式化给定日期(应该是GMT)。

默认情况下,我们返回相对时间(例如,“2分钟前”)。您可以使用返回绝对日期字符串relative=False。

您可以强制使用完整格式的日期(“1980年7月10日”) full_format=True。

此方法主要用于过去的日期。对于未来的日期,我们将回归到完整格式。

format_day(date,gmt_offset = 0,dow = True )[来源]

将给定日期格式化为星期几。

示例:“1月22日星期一”。您可以删除星期几 dow=False。

list(部分)[来源]

返回给定列表部件的逗号分隔列表。

对于大小为1的列表,格式是例如“A,B和C”,“A和B”或仅“A”。

friendly_number(值)[来源]

返回给定整数的逗号分隔数。

class tornado.locale.CSVLocale(代码,翻译)[来源]

使用龙卷风的CSV翻译格式实现区域设置。

class tornado.locale.GettextLocale(代码,翻译)[来源]

使用gettext模块的区域设置实现。

pgettext(context,message,plural_message = None,count = None )[来源] 允许设置翻译上下文,接受复数形式。

用法示例:

pgettext("law", "right")
pgettext("good", "right")

多个消息示例:

pgettext("organization", "club", "clubs", len(clubs))
pgettext("stick", "club", "clubs", len(clubs))

要使用上下文生成POT文件,请将以下选项添加到load_gettext_translations序列的第1步:

xgettext [basic options] --keyword=pgettext:1c,2 --keyword=pgettext:1c,2,3

第一种路由改装饰器方式

import tornado
import tornado.web
import tornado.ioloop


class RouterConfig:

    def __init__(self):
        self.Application = tornado.web.Application()

    def route(self, handler):
        self.Application.add_handlers(".*$", [(handler.URL, handler)])


app = RouterConfig()


@app.route
class Main1(tornado.web.RequestHandler):
    URL = r"/"

    def get(self, *args, **kwargs):
        self.finish("ok")


if __name__ == '__main__':
    app.Application.listen(8000)
    tornado.ioloop.IOLoop.instance().start()

第二种路由改装饰器方式

import tornado.web
import tornado.ioloop


class Route(object):

    def __init__(self):
        self.urls = list()

    def __call__(self, url, *args, **kwargs):
        def register(cls):
            self.urls.append((url, cls))
            return cls
        return register


route = Route()


@route(r"/")
class Main2(tornado.web.RequestHandler):

    def get(self, *args, **kwargs):
        self.finish("ok")


if __name__ == '__main__':
    app = tornado.web.Application(route.urls)
    app.listen(8000)
    tornado.ioloop.IOLoop.instance().start()

第三种路由改装饰器方式

import tornado.web
import tornado.ioloop


class RouterConfig(tornado.web.Application):

    def route(self, url):
        def register(handel):
            self.add_handlers(".*$", [(url, handel)])
            return handel
        return register


app = RouterConfig(cookie_secret="ulb7bEIZmwpV545Z")


@app.route(r"/")
class Main3(tornado.web.RequestHandler):

    def get(self, *args, **kwargs):
        self.finish("ok")


if __name__ == '__main__':
    app.listen(8000)
    tornado.ioloop.IOLoop.instance().start()
收藏
评论区

相关推荐

Tornado API 服务开发
本文讲述如何使用 Tornado(http://www.tornadoweb.org/) Web 框架来开发一个简单的 API 服务,以及如何使用 Docker 工具来构建镜像和部署服务。项目代码已在 GitHub 开源,JW Tornado Demo(https://github.com/jaggerwang/jwtornadodemo)。
tornado入门笔记
官方文档https://www.tornadoweb.org/en/stable/ 简单使用 /usr/bin/env python coding: utf8 Author: Wjyimport tornado.ioloop 启动import tornado.web 请求对象import tornado.tem
浅析常用的Python Web的几大框架
在各种语言平台中,python涌现的web框架恐怕是最多的,是一个百花齐放的世界,各种microframework、framework不可胜数;猜想原因应该是在python中构造框架十分简单,使得轮子不断被发明。所 以在Python社区总有关于Python框架孰优孰劣的话题。下面就给大家介绍一下python的几大框架: Django Django 应该是最出
Beego:简约 & 强大并存的 Go 应用框架
![](http://www.primeton.com/uploads/image/20191120/20191120162521_87647.jpg) 转载本文需注明出处:微信公众号EAWorld,违者必究。 引言: Beego 是一个快速开发 Go 应用的 HTTP 框架,他可以用来快速开发 API、Web 及后端服务等各种应用,
CentOS升级Python到2.7版本
查看python的版本 python -V Python 2.4.3 1.先安装GCC yum -y install gcc 2.下载Python-2.7.2 wget http://python.org/ftp/python/2.7.2/Python-2.7.2.tar.bz2 3.解压Python-2.7.2
Flask
Python 现阶段三大主流Web框架 Django Tornado Flask 对比 =========================================== [**百度百科**](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fbaike.baidu.com%2Fitem
Flask最强攻略
首先,要看你学没学过Django 如果学过Django 的同学,请从头看到尾,如果没有学过Django的同学,并且不想学习Django的同学,轻饶过第一部分 ### 一. Python 现阶段三大主流Web框架 Django Tornado Flask 对比 1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form
FreeBSD python安装MySQL
fetch https://pypi.python.org/packages/source/M/MySQL-python/MySQL-python-1.2.4.zip unzip MySQL-python-1.2.4.zip cd MySQL-python-1.2.4 python setup.py install ln -s /usr/loca
Nginx + tornado + supervisor部署
参考链接:[supervisor + Tornado + Nginx 使用详解](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fwww.liaoqiqi.com%2Fpost%2F18), [用tornado ,Supervisord ,nginx架网站](https://www.oschi
Python Tornado搭建高并发Restful API接口服务
#### Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快能实现高并发。得利于其 非阻塞的方式和对epoll的运用,Tornado 每秒可以处理数以千计的连接,这意味着对于实时 Web 服务来说,Tornado 是一个理想的 Web 框架。Tornado不同于其他pytho
Python 异步编程再添一利器
> GINO 填补了国内外 asyncio ORM 领域的空白 随着 Tornado 和 asyncio 等框架的陆续涌现,Python 异步编程这个话题也在逐渐升温。在这个烧脑的异步世界里,有没有办法可以既方便快捷、又简单明了地访问数据库呢?GitHub 千星项目 [GINO](https://www.oschina.net/action/GoToLin
Python进阶丨如何创建你的第一个Python元类?
> **摘要:**通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类。 Python元类设置类的行为和规则。元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一。通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类。本文介绍以下概念: * * 什么是Python元类?
tornado+peewee
##### 前言: * 需要异步操作MySQL,又要用orm,使用sqlalchemy需要加celery,觉得比较麻烦,选择了peewee-async ##### 开发环境 python3.6.8+peewee-async0.5.12+peewee2.10.2 * 数据库:MySQL,使用peewee-async需要依赖库 pip instal
tornado框架&三层架构&MVC&MTV&模板语言&cookie&session
web框架的本质其实就是`socket`服务端再加上业务逻辑处理, 比如像是`Tornado`这样的框架. 有一些框架则只包含业务逻辑处理, 例如`Django`, `bottle`, `flask`这些框架, 它们的使用需要依赖包含`socket`的第三方模块(即 `wsgiref`)来运行 在python中常见的web框架构建模式有以下两种:
tornado配合celery及rabbitmq实现web request异步非阻塞
Tornado和Celery介绍 ================ 1.Tornado --------- > Tornado是一个用python编写的一个强大的、可扩展的异步HTTP服务器,同时也是一个web开发框架。tornado是一个非阻塞式web服务器,其速度相当快。得利于其非阻塞的方式和对 epoll的运用,tornado每秒可以处理数以千计的