官方文档
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
翻译您的应用需要三个步骤:
生成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 )[来源] 允许设置翻译上下文,接受复数形式。
用法示例:
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()