tornado入门笔记

官方文档

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

简单使用

1# !/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Author: Wjy 4import tornado.ioloop # 启动 5import tornado.web # 请求对象 6import tornado.template # 模板 7 8 9class Index(tornado.web.RequestHandler): 10 def get(self, *args, **kwargs): 11 self.write("首页123") 12 13 14def make_app(): 15 return tornado.web.Application([ 16 (r"/index", Index) 17 ]) # debug=True会自动加载改变的py文件,不过会导致自动挂载后台 18 19 20if __name__ == '__main__': 21 app = make_app() 22 app.listen(8000) 23 tornado.ioloop.IOLoop.current().start()

单进程

1# -*- coding: utf-8 -*- 2# Author: Wjy 3import tornado.ioloop # 启动 4import tornado.web # 请求对象 5import tornado.template # 模板 6import tornado.autoreload 7import tornado.netutil 8import tornado.process 9from tornado.httpserver import HTTPServer 10 11 12class Index(tornado.web.RequestHandler): 13 def get(self, *args, **kwargs): 14 self.write("首页123") 15 16 17if __name__ == '__main__': 18 tornado.autoreload = True # debug模式 19 app = tornado.web.Application([ 20 (r"/index", Index) 21 ]) # debug=True会自动加载改变的py文件,不过会导致自动挂载后台 22 http = tornado.httpserver.HTTPServer(app) 23 http.listen(8000) 24 tornado.ioloop.IOLoop.current().start()

多进程

1# !/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Author: Wjy 4import tornado.ioloop # 启动 5import tornado.web # 请求对象 6import tornado.template # 模板 7import tornado.httpserver 8 9 10class MainHandler(tornado.web.RequestHandler): 11 def get(self, *args, **kwargs): 12 # 获取get请求一个参数 13 print(self.get_argument("a")) 14 # 获取get请求中参数列表 15 print(self.get_arguments("b")) 16 self.write("get 请求") 17 18 def post(self, *args, **kwargs): 19 # 获取表单数据 20 # print(self.get_body_argument("name")) 21 # 获取表单列表数据 22 # print(self.get_body_arguments("body")) 23 # 获取body原始数据 24 print(self.request.body) 25 # 获取请求头 26 print(self.request.headers) 27 self.write("post 请求") 28 29 def head(self, *args, **kwargs): 30 self.write("head 请求") 31 32 def delete(self, *args, **kwargs): 33 self.write("delete 请求") 34 35 def patch(self, *args, **kwargs): 36 self.write("patch 请求") 37 38 def put(self, *args, **kwargs): 39 self.write("put 请求") 40 41 def options(self, *args, **kwargs): 42 self.write("options 请求") 43 44 45 def prepare(self): 46 ''' 47 前置钩子 48 :return: 49 ''' 50 # self.write("prepare 前置钩子") 51 52 def on_finish(self): 53 ''' 54 后置钩子 55 :return: 56 ''' 57 # self.write("on_finish 后置钩子") 58 59 def initialize(self): 60 ''' 61 钩子 62 :return: 63 ''' 64 # self.write("initialize 每次都会被调用的钩子") 65 66 67class Index(tornado.web.RequestHandler): 68 def get(self, *args, **kwargs): 69 self.write("首页123") 70 71 72if __name__ == '__main__': 73 make_app = tornado.web.Application([ 74 (r"/", MainHandler), 75 (r"/index", Index) 76 ]) 77 app = tornado.httpserver.HTTPServer(make_app) # 标准写法 78 app.bind(8000) 79 app.start(1) # 多进程控制 80 tornado.ioloop.IOLoop.current().start()

说明:

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

1.关于app.listen()

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

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

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

2.关于多进程

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

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

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

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

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

Application中settings可以设置的参数

1#设置templates路径: 2template_path = os.path.join(os.path.dirname(__file__), "templates") 3 4#设置静态文件解析路径: 5static_path = os.path.join(os.path.dirname(__file__), "static"), 6 7#设置防跨站请求攻击: 8xsrf_cookies = True, 9# {% module xsrf_form_html() %} html中加入该参数 10#默认为False,即不可防御。 11 12#设置登陆路径,未登陆用户在操作时跳转会用到这个参数: 13login_url = "/login-do", 14#默认为@tornado.web.authenticated 15 16#设置调试模式: 17debug = True, 18#默认为False,即不是调试模式。 19 20#设置cookie密钥: 21cookie_secret = "dskfhisdjklagkfdklag;lkjasdklgjkldsjaklgjkldsfksdklf" 22#默认为字符串"secure cookies" 23 24#设置是否自动编码:在2.0以上需要设置此项来兼容您之前的APP 25autoescape = None, 26#不设置默认为自动编码。 27 28#设置template_loader,可以从独立的路径中导入template: 29template_loader=utils.ZipLoader, 30#其中utils为自己定义的模块,ZipLoader是tornado.template.BaseLoader的子类。 31 32#设置gzip压缩: 33gzip=True 34 35#设置静态路径头部: 36static_url_prefix = "/mystatic/", 37#默认是"/static/" 38 39#设置静态文件处理类: 40static_handler_class = MyStaticFileHandler, 41#默认是tornado.web.StaticFileHandler 42 43#设置静态文件的参数: 44static_handler_args = { "key1":"value1", "key2":"value2" } 45#默认为空字典。 46 47#设置日志处理函数 48log_function = your_fun, 49# 日志处理函数your_fun,按照自己的意图记录日志。

define和options

1# !/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Author: Wjy 4import tornado.ioloop # 启动 5import tornado.web # 请求对象 6import tornado.httpserver 7from tornado.options import options, define 8 9# 定义全局变量,options.出定义的这个变量 10define("port", default=8000, help="监听的端口") 11 12 13class Index(tornado.web.RequestHandler): 14 def get(self, *args, **kwargs): 15 self.write("首页123") 16 17 18if __name__ == '__main__': 19 tornado.autoreload = True # debug模式 20 app = tornado.web.Application([ 21 (r"/index", Index) 22 ]) 23 http = tornado.httpserver.HTTPServer(app) 24 http.listen(options.port) 25 tornado.ioloop.IOLoop.current().start()

模板基础

1# !/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Author: Wjy 4import tornado.ioloop # 启动 5import tornado.web # 请求对象 6import tornado.httpserver # http服务 7import tornado.template # 模板的使用 8import tornado.autoreload 9from tornado.options import options, define 10 11# 定义全局变量,options.出定义的这个变量 12define("port", default=8000, help="监听的端口") 13 14 15class Index(tornado.web.RequestHandler): 16 def get(self, *args, **kwargs): 17 # 构建模板 18 t = tornado.template.Template("<html>{{ myvalue }}</html>") 19 # 填充模板参数 20 self.write(t.generate(myvalue="hello1")) 21 22 23if __name__ == '__main__': 24 25 app = tornado.web.Application([ 26 (r"/index", Index) 27 ]) 28 http = tornado.httpserver.HTTPServer(app) 29 http.listen(options.port) 30 31 instance = tornado.ioloop.IOLoop.instance().start()

模板语法参考

1模板表达式由双花括号包围:。内容可以是任何python表达式,它将根据当前的autoescape设置进行转义并插入到输出中。其他模板指令使用。{{ ... }}{% %} 2 3要注释掉一个部分,使其从输出中省略,请用它包围。{# ... #} 4 5这些标签可以被转义为{{!{%!以及{#! 如果需要包括文字{{{%{#在输出中。 6 7{% apply *function* %}...{% end %} 8将函数应用于apply 和之间的所有模板代码的输出end: 9 10{% apply linkify %}{{name}} said: {{message}}{% end %} 11请注意,作为实现细节,应用块实现为嵌套函数,因此可能与通过设置的变量或使用或 在循环内进行奇怪的交互。{% set %}{% break %}{% continue %} 12 13{% autoescape *function* %} 14设置当前文件的自动调用模式。这不会影响其他文件,甚至是那些引用的文件。请注意,也可以在 或者全局配置自动加载:{% include %}ApplicationLoader 15 16{% autoescape xhtml_escape %} 17{% autoescape None %} 18{% block *name* %}...{% end %} 19表示用于的可命名的可替换块。父模板中的块将替换为子模板中同名块的内容:{% extends %}
1<!-- base.html --> 2<title>{% block title %}Default title{% end %}</title> 3 4<!-- mypage.html --> 5{% extends "base.html" %} 6{% block title %}My page title{% end %} 7{% comment ... %} 8将从模板输出中删除的注释。请注意,没有标签; 评论从单词 到结束标记。{% end %}comment%} 9{% extends *filename* %}
1从另一个模板继承。使用的模板extends应包含一个或多个block标记,以替换父模板中的内容。子block 标记中未包含在标记中的任何内容都将被忽略。有关示例,请参阅标记。{% block %} 2{% for *var* in *expr* %}...{% end %} 3与python for语句相同。 并且 可以在循环内使用。{% break %}{% continue %} 4{% from *x* import *y* %} 5与python import语句相同。 6{% if *condition* %}...{% elif *condition* %}...{% else %}...{% end %} 7条件语句 - 输出条件为真的第一部分。(这些elif和else部分是可选的) 8{% import *module* %} 9与python import语句相同。 10{% include *filename* %} 11包含另一个模板文件。包含的文件可以看到所有局部变量,就好像它被直接复制到include 指令点(该指令是一个例外)。或者,可以用于包括具有隔离命名空间的另一个模板。{% autoescape %}{% module Template(filename, **kwargs) %} 12{% module *expr* %} 13呈现一个UIModule。该输出UIModule未转义: 14 15{% module Template("foo.html", arg=42) %} 16UIModules是tornado.web.RequestHandler 类的一个特性(特别是它的render方法),当模板系统在其他环境中单独使用时,它将不起作用。 17 18{% raw *expr* %} 19输出给定表达式的结果而不进行自动转换。 20{% set *x* = *y* %} 21设置局部变量。 22{% try %}...{% except %}...{% else %}...{% finally %}...{% end %} 23与python try语句相同。 24{% while *condition* %}... {% end %} 25与python while语句相同。 并且 可以在循环内使用。{% break %}{% continue %} 26{% whitespace *mode* %} 27为当前文件的其余部分设置空白模式(或直到下一个指令)。请参阅 可用选项。Tornado 4.3中的新功能。{% whitespace %}filter_whitespace

类引用

1class tornado.template.Template(template_string,name =<string>”,loader = None,compress_whitespace = None,autoescape =“xhtml_escape”,whitespace = None[source] 2编译模板。 3 4我们从给定的template_string编译成Python。您可以使用generate()从变量生成模板。

构造一个模板。

参数:

1template_string(str) - 模板文件的内容。 2name(str) - 加载模板的文件名(用于错误消息)。 3loader(tornado.template.BaseLoader) - BaseLoader负责此模板,用于解析和指令。{% include %}{% extend %} 4compress_whitespace(bool) - 自Tornado 4.3以来已弃用。相当于whitespace="single"if和 whitespace="all"false5autoescape(str) - 模板命名空间中函数的名称,或None默认情况下禁用转义。 6whitespace(str) - 指定空白处理的字符串; 看看filter_whitespace选项。 7版本4.3更改:添加whitespace参数; 已弃用compress_whitespace。 8 9generate(** kwargs )[来源] 10使用给定的参数生成此模板。 11 12class tornado.template.BaseLoader(autoescape ='xhtml_escape',namespace = None,whitespace = None[来源] 13模板加载器的基类。 14 15您必须使用模板加载器来使用和等模板结构 。加载程序在第一次加载后缓存所有模板。{% extends %}{% include %}
构造模板加载器。

参数:

1autoescape(str) - 模板命名空间中函数的名称,例如“xhtml_escape”,或None默认情况下禁用自动转义。 2namespace(dict) - 要添加到默认模板名称空间的字典,或None。 3whitespace(str) - 一个字符串,指定模板中空格的默认行为; 看看filter_whitespace选项。对于以“.html”和“.js”结尾的文件,默认为“single”,对于其他文件,默认为“all”。 4版本4.3中已更改:已添加whitespace参数。 5 6reset()[来源] 7重置已编译模板的缓存。 8 9resolve_path(name,parent_path = None[来源] 10将可能相对路径转换为绝对路径(在内部使用)。 11 12load(name,parent_path = None[来源] 13加载模板。 14 15class tornado.template.Loader(root_directory,** kwargs )[来源] 16从单个根目录加载的模板加载器。 17 18class tornado.template.DictLoader(dict,** kwargs )[来源] 19从字典加载的模板加载器。 20 21异常tornado.template.ParseError(消息,文件名=无,行号= 0[来源] 22引发模板语法错误。 23 24ParseError实例具有指示错误位置的属性filename和lineno属性。 25 26版本4.3中已更改:已添加filename和lineno属性。 27 28tornado.template.filter_whitespace(模式,文字)[来源] 29text根据变换空格mode。

可用的模式是:

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

模板应用py文件

1# !/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Author: Wjy 4import tornado.ioloop # 启动 5import tornado.web # 请求对象 6import tornado.httpserver # http服务 7import tornado.template # 模板的使用 8import tornado.autoreload 9from tornado.options import options, define 10 11# 定义全局变量,options.出定义的这个变量 12define("port", default=8000, help="监听的端口") 13 14 15class Index(tornado.web.RequestHandler): 16 def get(self, *args, **kwargs): 17 students = [dict(name='david'), dict(name='jack')] 18 19 # 原始写法 20 # loader = tornado.template.Loader("templates") 21 # t = loader.load("base.html") 22 # self.write(t.generate(students=students)) 23 24 self.render("test.html", students=students) 25 26 27if __name__ == '__main__': 28 29 app = tornado.web.Application([ 30 (r"/index", Index) 31 ], 32 template_path="./templates" # 与render配合使用 33 ) 34 http = tornado.httpserver.HTTPServer(app) 35 http.listen(options.port) 36 37 instance = tornado.ioloop.IOLoop.current().start()

base.html

1<html> 2 <head> 3 <title>{% block title %}Default title{% end %}</title> 4 </head> 5 <body> 6 <ul> 7 {% for student in students %} 8 {% block student %} 9 <li>{{ escape(student['name']) }}</li> 10 {% end %} 11 {% end %} 12 </ul> 13 </body> 14</html>

test.html

1{% extends "base.html" %} 2 3{% block title %}A bolder title{% end %} 4 5{% block student %} 6 <li><span style="bold">{{ escape(student['name']) }}</span></li> 7{% end %}

路由的实现

tornado.routing- 基本路由实现

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

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

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

1class CustomRouter(Router): 2 def find_handler(self, request, **kwargs): 3 # some routing logic providing a suitable HTTPMessageDelegate instance 4 return MessageDelegate(request.connection) 5 6class MessageDelegate(HTTPMessageDelegate): 7 def __init__(self, connection): 8 self.connection = connection 9 10 def finish(self): 11 self.connection.write_headers( 12 ResponseStartLine("HTTP/1.1", 200, "OK"), 13 HTTPHeaders({"Content-Length": "2"}), 14 b"OK") 15 self.connection.finish() 16 17router = CustomRouter() 18server = HTTPServer(router)

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

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

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

1resources = {} 2 3class GetResource(RequestHandler): 4 def get(self, path): 5 if path not in resources: 6 raise HTTPError(404) 7 8 self.finish(resources[path]) 9 10class PostResource(RequestHandler): 11 def post(self, path): 12 resources[path] = self.request.body 13 14class HTTPMethodRouter(Router): 15 def __init__(self, app): 16 self.app = app 17 18 def find_handler(self, request, **kwargs): 19 handler = GetResource if request.method == "GET" else PostResource 20 return self.app.get_handler_delegate(request, handler, path_args=[request.path]) 21 22router = HTTPMethodRouter(Application()) 23server = HTTPServer(router)

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

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

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

一个例子HTTPServerConnectionDelegate:

1router = RuleRouter([ 2 Rule(PathMatches("/handler"), ConnectionDelegate()), 3 # ... more rules 4]) 5 6class ConnectionDelegate(HTTPServerConnectionDelegate): 7 def start_request(self, server_conn, request_conn): 8 return MessageDelegate(request_conn)

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

1router = RuleRouter([ 2 Rule(PathMatches("/callable"), request_callable) 3]) 4 5def request_callable(request): 6 request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK") 7 request.finish() 8

另一个Router例子:

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

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

1router = RuleRouter([ 2 Rule(HostMatches("example.com"), RuleRouter([ 3 Rule(PathMatches("/app1/.*"), Application([(r"/app1/handler", Handler)]))), 4 ])) 5]) 6 7server = HTTPServer(router)

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

1app1 = Application([ 2 (r"/app1/handler", Handler1), 3 # other handlers ... 4]) 5 6app2 = Application([ 7 (r"/app2/handler", Handler2), 8 # other handlers ... 9]) 10 11router = RuleRouter([ 12 Rule(PathMatches("/app1.*"), app1), 13 Rule(PathMatches("/app2.*"), app2) 14]) 15 16server = HTTPServer(router)

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

4.5版中的新功能。

class tornado.routing.Router[source]

抽象路由器接口。

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

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

参数:

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

返回:

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

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

reverse_url(name,* args )[来源]

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

参数:

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

基于规则的路由器实现。

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

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

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

1RuleRouter([ 2 (PathMatches("/handler"), Target), 3])

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

1RuleRouter([ 2 ("/handler", Target), 3])

在上面的示例中,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(值)[来源]
1转义字符串,使其在HTMLXML中有效。 2 3转义字符<>,",',和&。在属性值中使用时,转义字符串必须用引号括起来。 4 5版本3.2中已更改:将单引号添加到转义字符列表中。
tornado.escape.xhtml_unescape(值)[来源]
取消转义XML转义字符串。
tornado.escape.url_escape(value,plus = True )[来源]
1返回给定值的URL编码版本。 2 3如果plus为true(默认值),则空格将表示为“+”而不是“%20”。这适用于查询字符串,但不适用于URL的路径组件。请注意,此默认值与Python的urllib模块相反。 4 5新的3.1版:该plus参数
tornado.escape.url_unescape(value,encoding ='utf-8',plus = True )[来源]
1URL解码给定值。 2 3参数可以是字节或unicode字符串。 4 5如果encoding是None,则结果将是字节字符串。否则,结果是指定编码中的unicode字符串。 6 7如果plus为真(默认值),加号将被解释为空格(文字加号必须表示为“%2B”)。这适用于查询字符串和表单编码值,但不适用于URL的路径组件。请注意,此默认值与Python的urllib模块相反。 8 9新的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(值)[来源]
1将字符串参数转换为字节字符串。 2 3如果参数已经是字节字符串或None,则返回不变。否则它必须是unicode字符串并编码为utf8。
tornado.escape.to_unicode(值)[来源]
1将字符串参数转换为unicode字符串。 2 3如果参数已经是unicode字符串或None,则返回不变。否则它必须是字节字符串并解码为utf8。 4 5tornado.escape.native_str() 6将字节或unicode字符串转换为类型str。相当于 utf8Python 2和to_unicodePython 3
tornado.escape.to_basestring(值)[来源]
1将字符串参数转换为basestring的子类。 2 3在python2中,byte和unicode字符串大多可以互换,因此处理用户提供的参数和ascii字符串常量的函数可以使用任何一个并且应该返回用户提供的类型。在python3中,这两种类型不可互换,因此需要此方法将字节字符串转换为unicode。
tornado.escape.recursive_unicode(obj )[来源]
1走一个简单的数据结构,将字节串转换为unicode。 2 3支持列表,元组和词典。
杂项功能
1tornado.escape.linkify(text,shorten = False,extra_params ='',require_protocol = False,allowed_protocols = ['http''https'][source] 2使用链接将纯文本转换为HTML3 4例如:会回来 linkify("Hello http://tornadoweb.org!")Hello <a href="http://tornadoweb.org">http://tornadoweb.org</a>! 5 6参数: 7 8- shorten:长网将缩短显示。 9 10- extra_params:要包含在链接标记中的额外文本,或者将链接作为参数并返回额外文本的可调用文件,例如,或:linkify(text, extra_params='rel="nofollow" class="external"') 11 12def extra_params_cb(url): 13 if url.startswith("http://example.com"): 14 return 'class="internal"' 15 else: 16 return 'class="external" rel="nofollow"' 17linkify(text, extra_params=extra_params_cb) 18- require_protocol:仅链接包含协议的URL。如果这是假的,那么诸如www.facebook.com之类的网址也将被链接。 19 20- permitted_protocols:列出(或设置)应该链接的协议,例如。包含诸如的协议是非常不安全的 。linkify(text, permitted_protocols=["http", "ftp", "mailto"])javascript
tornado.escape.squeeze(值)[来源]
用单个空格替换所有空白字符序列。

tornado.locale- 国际化支持

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

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

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

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

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

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

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

tornado.locale.get(* locale_codes )[来源]
1返回给定区域设置代码的最接近匹配项。 2 3我们按顺序迭代所有给定的区域设置代码。如果我们对代码有一个紧密或松散的匹配(例如,“en”代表“en_US”),我们返回语言环境。否则,我们移动到列表中的下一个代码。 4 5默认情况下,en_US如果找不到任何指定语言环境的翻译,则返回。您可以使用更改默认语言环境 set_default_locale()
tornado.locale.set_default_locale(代码)[来源]
1设置默认语言环境。 2 3假定默认语言环境是用于系统中所有字符串的语言。从磁盘加载的转换是从默认语言环境到目标语言环境的映射。因此,您无需为默认语言环境创建转换文件。
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:

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

版本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 )[来源] 允许设置翻译上下文,接受复数形式。

用法示例:

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

多个消息示例:

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

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

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

第一种路由改装饰器方式

1import tornado 2import tornado.web 3import tornado.ioloop 4 5 6class RouterConfig: 7 8 def __init__(self): 9 self.Application = tornado.web.Application() 10 11 def route(self, handler): 12 self.Application.add_handlers(".*$", [(handler.URL, handler)]) 13 14 15app = RouterConfig() 16 17 18@app.route 19class Main1(tornado.web.RequestHandler): 20 URL = r"/" 21 22 def get(self, *args, **kwargs): 23 self.finish("ok") 24 25 26if __name__ == '__main__': 27 app.Application.listen(8000) 28 tornado.ioloop.IOLoop.instance().start()

第二种路由改装饰器方式

1import tornado.web 2import tornado.ioloop 3 4 5class Route(object): 6 7 def __init__(self): 8 self.urls = list() 9 10 def __call__(self, url, *args, **kwargs): 11 def register(cls): 12 self.urls.append((url, cls)) 13 return cls 14 return register 15 16 17route = Route() 18 19 20@route(r"/") 21class Main2(tornado.web.RequestHandler): 22 23 def get(self, *args, **kwargs): 24 self.finish("ok") 25 26 27if __name__ == '__main__': 28 app = tornado.web.Application(route.urls) 29 app.listen(8000) 30 tornado.ioloop.IOLoop.instance().start()

第三种路由改装饰器方式

1import tornado.web 2import tornado.ioloop 3 4 5class RouterConfig(tornado.web.Application): 6 7 def route(self, url): 8 def register(handel): 9 self.add_handlers(".*$", [(url, handel)]) 10 return handel 11 return register 12 13 14app = RouterConfig(cookie_secret="ulb7bEIZmwpV545Z") 15 16 17@app.route(r"/") 18class Main3(tornado.web.RequestHandler): 19 20 def get(self, *args, **kwargs): 21 self.finish("ok") 22 23 24if __name__ == '__main__': 25 app.listen(8000) 26 tornado.ioloop.IOLoop.instance().start()
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Python3:sqlalchemy对mysql数据库操作,非sql语句

Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''