文档章节

Python模板库Mako的用法

shaohan
 shaohan
发布于 2014/06/19 16:23
字数 1912
阅读 49
收藏 1
点赞 0
评论 0

Mako是一个高性能的Python模板库,它的语法和API借鉴了很多其他的模板库,如Django、Jinja2等等。

基本用法

创建模板并渲染它的最基本的方法是使用 Template 类:

from mako.template import Template

t = Template('hello world!')
print t.render()

传给 Template 的文本参数被编译为一个Python模块。模块包含一个 render_body() 函数,它产生模板的输出。调用 render() 方法时,Mako建立了一个模板的运行环境,并调用 render_body() 函数,把输出保存到缓冲,返回它的字符串内容。

render_body() 函数中可以访问一个变量集。可以向 render() 方法发送额外的关键词参数来指定这些变量:

from mako.template import Template

t = Template('hello, ${name}!')
print t.render(name='yeolar')

render() 方法使Mako创建一个 Context 对象,它存储模板可以访问的所有变量和一个用来保存输出的缓冲。也可以自己创建 Context ,用 render_context() 方法使模板用它来渲染:

from mako.template import Template
from mako.runtime import Context
from StringIO import StringIO

t = Template('hello, ${name}!')
buf = StringIO()
c = Context(buf, name='yeolar')
t.render_context(c)
print buf.getValue()

使用文件模板

Template 也可以从文件加载模板,使用 filename 参数:

from mako.template import Template

t = Template(filename='/docs/tpl.txt')
print t.render()

为了提高性能,从文件加载的 Template 还可以在文件系统中将生成的模块缓存为一般的Python模块文件(.py文件),这通过添加 module_directory 参数实现:

from mako.template import Template

t = Template(filename='/docs/tpl.txt', module_directory='/tmp/mako_modules')
print t.render()

上面的代码渲染后,会创建一个/tmp/mako_modules/docs/tpl.txt.py文件,其中包含模块的源代码。下次同样参数的 Template 创建时,自动重用这个模块文件。

使用TemplateLookup

到现在的例子都是有关单个 Template 对象的用法。如果模板中的代码要定位其他模板资源,需要某种使用URI来找到它们的方法。这种需求是由 TemplateLookup 类来达到的。这个类通过传入一个模板查找目录的列表来构造,然后作为关键词参数传给 Template 对象:

from mako.template import Template
from mako.lookup import TemplateLookup

lookup = TemplateLookup(directories=['/docs'])
t = Template('<%include file="header.txt" /> hello word!', lookup=lookup)

上面创建的模板中包含文件header.txt。为了查找header.txt,传了一个 TemplateLookup 对象给它。

通常,应用会以文本文件形式在文件系统上存储大部分或全部的模板。一个真正的应用会直接从 TemplateLookup 取得它的模板,使用 get_template() 方法,它接受需要的模板的URI作为参数:

from mako.template import Template
from mako.lookup import TemplateLookup

lookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules')

def serve_template(t_name, **kwargs):
t = lookup.get_template(t_name)
print t.render(**kwargs)

上面的例子中我们创建了一个 TemplateLookup ,它从/docs目录中查找模板,并把所有的模块文件存储到/tmp/mako_modules目录中。通过将传入的URI附加到每个查找目录来定位模板,如传递/etc/beans/info.txt,将查找文件/docs/etc/beans/info.txt,如果没找到将抛出 TopLevelNotFound 异常。

当定位到模板的时候,传给 get_template() 调用的URI也会作为 Template 的 uri 属性。 Template 使用这个URI来得到模块文件的名字,因此上面的例子中对/etc/beans/info.txt会创建模块文件/tmp/mako_modules/etc/beans/info.txt.py。

设置收集的大小

TemplateLookup 还满足将内存中缓存的模板总数设为一个固定的值。默认情况 TemplateLookup 大小是不限的。可以用 collection_size 参数指定一个固定值:

lookup = TemplateLookup(directories=['/docs'], module_directory='/tmp/mako_modules', collection_size=500)

上面的 lookup 将模板加载到内存中的上限是500个。之后,它将使用LRU策略来清理替换模板。

设置文件系统检查

TemplateLookup 的另一个重要标志是 filesystem_checks 。默认为 True ,每次 get_template() 方法返回一个模板,会比较原始模板文件的修改时间和模板的最近加载时间,如果文件更新,就重新加载和编译模板。在生产系统中,将 filesystem_checks 设为 False 能获得一些性能的提升。

使用Unicode和编码

Template 和 TemplateLookup 可以设置 output_encoding 和 encoding_errors 参数来将输出编码为Python支持的编码格式:

from mako.template import Template
from mako.lookup import TemplateLookup

lookup = TemplateLookup(directories=['/docs'], output_encoding='utf-8', encoding_errors='replace')
t = lookup.get_template('foo.txt')
print t.render()

使用Python 3时,如果设置了 output_encoding , render() 方法将返回一个 bytes 对象,否则返回 string 。

render_unicode() 方法返回模板输出为Python unicode 对象,Python 3为 string :

print t.render_unicode()
上面的方法没有输出编码的参数,可以自行编码:

print t.render_unicode().encode('utf-8', 'replace')

注意Mako中模板的底层输出流是Python Unicode对象。

处理异常

模板异常可能发生在两个地方。一个是当你查找、解析和编译模板的时候,一个是运行模板的时候。模板运行中发生的异常会正常在产生问题的Python代码处抛出。Mako有自己的一组异常类,它们主要用于模板构造的查找和编译阶段。Mako提供了一些库例程用来对异常栈提供Mako的信息,并将异常输出为文本或HTML格式。Python文件名、行号和代码片段会被转换为Mako模板文件名、行号和代码片段。Mako模板模块的行会被转换为原始的模板文件对应行。

text_error_template() 和 html_error_template() 函数用于格式化异常跟踪。它们使用 sys.exc_info() 来得到最近抛出的异常。这些处理器的用法像下面这样:

from mako import exceptions

try:
t = lookup.get_template(uri)
print t.render()
except:
print exceptions.text_error_template().render()

或者渲染为HTML:

from mako import exceptions

try:
t = lookup.get_template(uri)
print t.render()
except:
print exceptions.html_error_template().render()

html_error_template() 模板接受两个选项:指定 full=False 只渲染HTML的一节,指定 css=False 关闭默认的样式表。如:

print exceptions.html_error_template().render(full=False)

HTML渲染函数也可以用 format_exceptions 标志加到 Template 中。这种情况下,模板在渲染阶段的任何异常在输出中的结果都会替换为 html_error_template() 的输出:

t = Template(filename='/foo/bar', format_exceptions=True)
print t.render()

注意上面模板的编译阶段发生在构造 Template 时,没有定义输出流。因此查找、解析、编译阶段发生的异常正常情况下不会被处理,而是传播下去。渲染前的追溯不包括Mako形式的行,这意味着渲染前和渲染中发生的异常会用不同的方式处理,因此 try/except 可能更常用。

错误模板函数使用的底层对象是 RichTraceback 对象。这个对象也可以直接用来提供自定义的错误视图。下面是一个用法的样例:

from mako.exceptions import RichTraceback

try:
t = lookup.get_template(uri)
print t.render()
except:
traceback = RichTraceback()
for (filename, lineno, function, line) in traceback.traceback:
print 'File %s, line %s, in %s' % (filename, lineno, function)
print line, '\n'
print '%s: %s' % (str(traceback.error.__class__.__name__), traceback.error)

集成Mako

在Django中集成Mako

通过Django的中间件可以集成Mako。首先需要安装django-mako模块。

在Django项目的settings.py文件中,修改 MIDDLEWARE_CLASSES ,添加 djangomako.middleware.MakoMiddleware 。使用 render_to_response() 函数即可使用:

from djangomako.shortcuts import render_to_response

def hello_view(request):
return render_to_response('hello.txt', {'name': 'yeolar'})

在Tornado中集成Mako

在Tornado中可以直接使用Mako,下面是一个使用示例:

import tornado.web
import mako.lookup
import mako.template

LOOK_UP = mako.lookup.TemplateLookup(
directories=[TEMPLATE_PATH], module_directory='/tmp/mako',
output_encoding='utf-8', encoding_errors='replace')

class BaseHandler(tornado.web.RequestHandler):
def initialize(self, lookup=LOOK_UP):
'''Set template lookup object, Defalut is LOOK_UP'''
self._lookup = lookup

def render_string(self, filename, **kwargs):
'''Override render_string to use mako template.

Like tornado render_string method, this method
also pass request handler environment to template engine.
'''
try:
template = self._lookup.get_template(filename)
env_kwargs = dict(
handler = self,
request = self.request,
current_user = self.current_user,
locale = self.locale,
_ = self.locale.translate,
static_url = self.static_url,
xsrf_form_html = self.xsrf_form_html,
reverse_url = self.application.reverse_url,
)
env_kwargs.update(kwargs)
return template.render(**env_kwargs)
except:
# exception handler
pass

def render(self, filename, **kwargs):
self.finish(self.render_string(filename, **kwargs))

class MainHandler(BaseHandler):
def get(self):
self.render('index.html', messages=[])

本文转载自:

共有 人打赏支持
shaohan
粉丝 10
博文 78
码字总数 57889
作品 0
海淀
项目经理
3 个 Python 模板库比较

你的下一个 Python 项目需要一个模板引擎来自动生成 HTML 吗?这有几种选择。 在我的日常工作中,我花费大量的时间将各种来源的数据转化为可读的信息。虽然很多时候这只是电子表格或某种类型...

20% ⋅ 06/05 ⋅ 0

Python模板库Mako的用法

Mako是一个高性能的Python模板库,它的语法和API借鉴了很多其他的模板库,如Django、Jinja2等等。 基本用法 创建模板并渲染它的最基本的方法是使用 Template 类: from mako.template impor...

北方攻城师 ⋅ 2014/07/14 ⋅ 0

Python模板库Mako的用法

Mako是一个高性能的Python模板库,它的语法和API借鉴了很多其他的模板库,如Django、Jinja2等等。 基本用法 创建模板并渲染它的最基本的方法是使用 Template 类: 传给 Template 的文本参数被...

楠木楠 ⋅ 2016/09/15 ⋅ 0

Mac下python2与python3共存问题

python从入门到放弃; mac os系统里面自带了python2,当我们需要学习python3的时候就要自己安装python3,就会出现python2与python3共存。新手不懂就会出现一系列的问题。 比如安装库的时候就...

服说八道 ⋅ 01/05 ⋅ 0

python有趣用法汇总(持续更新)

使用python过程中经常会不经意间遇到非常有趣的用法,于是特意搜集了一些 有趣的用法 1.for-else用法 循环正常结束则执行else语句。一般用于循环找符合条件的元素,如果找到则调出循环,不会...

p柯西 ⋅ 06/05 ⋅ 0

用mako增强django模板,用法像jsp

用mako增强django模板 django默认的模板功能还可以,但是不能直接用python的语法,mako解决了这个痛点,使得django的模板变得像jsp一样,可以直接使用python的语法做一些事情。 makodjango-m...

duoduo3_69 ⋅ 2014/09/25 ⋅ 5

django 1.8 官方文档翻译: 3-5-1 使用Django输出CSV

使用Django输出CSV 这篇文档阐述了如何通过使用Django视图动态输出CSV (Comma Separated Values)。 你可以使用Python CSV 库或者Django的模板系统来达到目的。 使用Python CSV库 Python自带了...

apachecn_飞龙 ⋅ 2015/09/04 ⋅ 0

Python安装MySQL库详解(解决Microsoft Visual C++ 9.0 is required )

前面我们介绍的Python网络爬虫通常将抓取的数据存储至TXT或CSV文件,而当数据量增加之时,就需要将其存储至本地数据库了。Python访问数据库需要对应的接口程序,我们可以把接口程序理解为Pyt...

eastmount ⋅ 04/25 ⋅ 0

Python、Lua和Ruby三大语言脚本哪家强?

这三种语言中的哪一种更合适你的项目?很大程度取决于你想达到什么样的目标。作为一书的结尾,在这一节里,我会描述一下它们各自的优点和不足。 Python的优点和不足 Python的优点如下: 1. P...

柯西带你学编程 ⋅ 06/01 ⋅ 0

如何解决Python包依赖问题

以简洁高效(指编程较为高效, 而不是运行速度)出名的Python, 在包依赖问题上有时候让人挠头. 一些新手复制了Github上的项目准备运行, 很多时候会在包依赖这一步上卡个半天.(这里推荐新手最好在...

謝增光_Feson ⋅ 05/27 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

关于“幂等”操作

一个幂等(idempotent)操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同. 开发中, 我们经常考虑幂等操作的场景有“接口调用”、“MQ消费”、“自动任务”等 接口调用, 可能出现...

零二一七 ⋅ 13分钟前 ⋅ 0

Dubbo服务服务暴露之ProxyFactory Invoker

Dubbo服务暴露过程中有涉及到调用ProxyFactory 中方法获取Invoker对象的过程,现在我们来深究下源码,来看下这个过程是在做些什么,返回的Invoker 对象是什么,我们来看一下代码的切入点: ...

哲别0 ⋅ 27分钟前 ⋅ 0

GP两种连接方式性能测试

GP两种连接方式性能测试 Pivotal import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; public class GPQueryStrin......

仔仔1993 ⋅ 32分钟前 ⋅ 0

jsonrpc-4j代码解析

解析文件 AutoJsonRpcServiceImplExporter JsonServiceExporter AutoJsonRpcServiceImplExporter 路径:com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter AutoJsonRpcServi......

郭恩洲_OSC博客 ⋅ 54分钟前 ⋅ 0

百度搜索

from selenium import webdriver import time brower=webdriver.Firefox() brower.get('http://www.baidu.com') input=brower.find_element_by_id('kw') input.send_keys('中南大学') time.s......

南桥北木 ⋅ 今天 ⋅ 0

tomcat 日志记录器

1、日志记录器是记录消息的组件 日志记录器需要与某个servlet 容器相关联 2、Logger 接口 共定义了5种日志级别:FATAL、ERROR、WARNING、INFORMATION、DEBUGGER setVerbosity 设置级别 setC...

职业搬砖20年 ⋅ 今天 ⋅ 0

Thrift RPC实战(三) Thrift序列化机制

1.Thrift基础架构 Thrift是一个客户端和服务端的架构体系,数据通过socket传输; 具有自己内部定义的传输协议规范(TProtocol)和传输数据标准(TTransports); 通过IDL脚本对传输数据的数据结构...

lemonLove ⋅ 今天 ⋅ 0

网站建设就要像2018世界杯的俄罗斯队大杀四方[图]

今天心情不错,因为昨天晚上观看了世界杯比赛,尤其是对俄罗斯队的大杀四方感到十分霸气侧漏啊,因此我联想到了自己的博客网站,我的博客是去年年底上线的,一直想建设一个关于读书和读后感作...

原创小博客 ⋅ 今天 ⋅ 0

linux 信号机制

signal(SIGPIPE, SIG_IGN); TCP是全双工的信道, 可以看作两条单工信道, TCP连接两端的两个端点各负责一条. 当对端调用close时, 虽然本意是关闭整个两条信道, 但本端只是收到FIN包. 按照TCP协...

xxdd ⋅ 今天 ⋅ 0

my.cnf, my-small.cnf, my-medium.cnf, my-large.cnf

1. my-small.cnf # Example MySQL config file for small systems.## This is for a system with little memory (<= 64M) where MySQL is only used# from time to time and it's importa......

周云台 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部