官方文档
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"false。 5autoescape(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转义字符串,使其在HTML或XML中有效。 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 )[来源]
1从URL解码给定值。 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使用链接将纯文本转换为HTML。 3 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
翻译您的应用需要三个步骤:
-
生成POT翻译文件:
xgettext --language=Python --keyword=_:1,2 -d mydomain file1.py file2.html etc
-
合并现有的POT文件:
msgmerge old.po mydomain.po > new.po
-
编译:
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()
