Python Web开发模板引擎优缺点总结

做 Web 开发少不了要与模板引擎打交道。我陆续也接触了 Python 的不少模板引擎,感觉可以总结一下了。

一、首先按照我的熟悉程度列一下:

pyTenjin:我在开发 Doodle 和 91 外教时使用。
Tornado.template:我在开发知乎日报时使用。
PyJade:我在开发知乎日报时接触过。
Mako:我只在一个早期就夭折了的小项目里用过。
Jinja2:我只拿它做过一些 demo。

其他就不提了,例如 Django 的模板,据说又慢又难用,我根本就没接触过。

二、再说性能

很多测试就是弄个大循环什么的,很没技术含量。其实模板的渲染时间主要消耗在字符串处理上,包括拼接、编码、转义等,而循环测的则是 Python runtime 的性能。

所以我还是用实际的例子来测试吧,最终选择了 Doodle 的首页。它有几个子模板、几个循环、几个函数调用和很多个变量,具有一定代表性。考虑到 pyTenjin 以外的模板引擎不支持局部缓存,我就把用到缓存的侧边栏去掉了,只渲染主体部分。

渲染 1000 次的结果为:pyTenjin 耗时 0.65 秒,取消预处理后耗时 0.9 秒;Tornado.template 耗时 1.0 秒;Jinja2 耗时 1.1 秒。

测试代码有几百行,19 个文件,我就懒得列出来了。其他模板引擎也懒得测了。

@pyTenjin 的优势很明显,特别是它支持预处理。这个预处理的主要作用是把一些常量先编译好,渲染时就不用再处理了(因为已经变成字符串了);此外,有些功能可以静态地决定是否开启,而预处理可以把那些不需要的功能代码(主要是 if 分支)提前去掉。此外还能缓存任意代码段的渲染结果,在一段时间内无需重新渲染。
@Jinja2 比 Tornado.template 慢是我没想到的,好像与很多测试不符。
@Mako 预计和 Jinja2 差不多。它也能缓存代码段的渲染结果。
@PyJade 需要把 Jade 模板转成其他模板,且无缓存,预计会慢很多。

考虑到除 PyJade 外肯定不存在几倍的性能差距,所以挑个好用的即可。

三、最后说易用性

@pyTenjin 的优点是可以写任意 Python 代码。
缺点是标记比较复杂和独特,有 <?py ... ?>、<?PY ... ?>、#{...}、#{{...}}、{==...==}、{#==...==#}、${...}、${{...}}、{#=...=#} 和 {#==...==#} 这么多种,不过看上去还挺萌的。
由于使用了 < 和 > 符号,在 HTML 标签内部使用时,会阻碍编辑器进行语法解析。
另外,它的 tagattr() 方法在 expr 参数为 0 时当成了 True 来处理,需要改源码来修正,而它又没有开源项目可以提交 pull request。
而且它只有一个开发者,已经有一年多没更新了,活跃度明显不够。

@Tornado.template 的优点是与 Tornado 搭配还不错(毕竟是自带的),功能和性能都还行。
缺点是出错时很难定位到是哪写错了,而且与其他模板引擎相比,功能确实少了点(不过我还没遇到不够用的情况)。
另外,{% raw ... %} 写起来好麻烦。None 在输出时会显示成 None,而不是空字符串,导致写起来很累。
它输出的 HTML 代码是去掉头尾空格的,不过单独的 Python 代码行会显示成空行,看上去比较怪。

@Jinja2 的优点是功能多,定义了很多辅助函数,有 filter,也有内联的 if 表达式这种语法糖,写起来比较舒服。此外,它能够调整空白,这使得它输出的 HTML 比较好看。
缺点是学习成本较高,语法也不是纯 Python 了,甚至不能 import Python 模块和使用 [item for item in list if item] 这种列表解析表达式。
另一个严重的缺点是不能输出非 ASCII 的字符串, 遇到这种情况必须使用 unicode 类型,但要保证这点很麻烦。

@Mako 的优点是和 pyTenjin 一样可以写任意 Python 代码,又和 Jinja2 一样支持 filter(其实习惯了函数调用的话)。
缺点也是学习成本较高,语法比较复杂,对 HTML 编辑器不友好。

@PyJade 的优点是写起来最快(特别是对前端而言),没什么多余的东西。
缺点和 Jinja2 一样,更惨的是它几乎没有文档,而且最新的 release 版不可用,需要用开发版。

目前看来,我还是继续用 pyTenjin 算了,其他的要么不好用,要么学习成本比较高,而且多出来的功能感觉并不是非有不可的。

(0)

相关推荐

  • 为Python的Tornado框架配置使用Jinja2模板引擎的方法

    tornado 默认有一个模板引擎但是功能简单(其实我能用到的都差不多)使用起来颇为麻烦, 而jinja2语法与django模板相似所以决定使用他. 下载jinja2 还是用pip 下载(用的真是爽) pip install jinja2 这样就可以使用了. tornado与jinja2 整合 tornado和jinja2整合起来很简单(其实是网上找的比较简单), 不知道从那里找到的反正找到了,不说了直接上代码 #coding:utf-8 import tornado.web from jinj

  • Python 模板引擎的注入问题分析

    这几年比较火的一个漏洞就是jinjia2之类的模板引擎的注入,通过注入模板引擎的一些特定的指令格式,比如 {{1+1}} 而返回了 2 得知漏洞存在.实际类似的问题在Python原生字符串中就存在,尤其是Python 3.6新增 f 字符串后,虽然利用还不明确,但是应该引起注意. 最原始的 % userdata = {"user" : "jdoe", "password" : "secret" } passwd = raw_i

  • 深入解析Python的Tornado框架中内置的模板引擎

    template中的_parse方法是模板文法的解析器,而这个文件中一坨一坨的各种node以及block,就是解析结果的承载者,也就是说在经过parse处理过后,我们输入的tornado的html模板就变成了各种block的集合. 这些block和node的祖宗就是这个"抽象"类, _Node,它定义了三个方法定义,其中generate方法是必须由子类提供实现的(所以我叫它"抽象"类).  理论上来说,当一个类成为祖宗类时,必定意味着这个类包含了一些在子类中通用的行

  • Python的Flask框架标配模板引擎Jinja2的使用教程

    Jinja2需要Python2.4以上的版本. 安装 按照Jinja有多种方式,你可以根据需要选择不同的按照方式. 使用easy_install 或pip: #sudo easy_install Jinja2 #sudo pip install Jinja2 这两个工具可以自动从网站上下载Jinja,并安装到python目录的site-packages目录中. 从tar包安装: # 下载Jinja的安装包 # 解压缩 # sudo python setup.py install 基本API用法

  • 常用python编程模板汇总

    在我们编程时,有一些代码是固定的,例如Socket连接的代码,读取文件内容的代码,一般情况下我都是到网上搜一下然后直接粘贴下来改一改,当然如果你能自己记住所有的代码那更厉害,但是自己写毕竟不如粘贴来的快,而且自己写的代码还要测试,而一段经过测试的代码则可以多次使用,所以这里我就自己总结了一下python中常用的编程模板,如果还有哪些漏掉了请大家及时补充哈. 一.读写文件 1.读文件 (1).一次性读取全部内容 filepath='D:/data.txt' #文件路径 with open(file

  • Python的Flask框架中的Jinja2模板引擎学习教程

    Flask的模板功能是基于Jinja2模板引擎来实现的.模板文件存放在当前目前下的子目录templates(一定要使用这个名字)下. main.py 代码如下: from flask import Flask, render_template app = Flask(__name__) @app.route('/hello') @app.route('/hello/<name>') def hello(name=None): return render_template('hello.html

  • Python的Django框架中模板碎片缓存简介

    你同样可以使用cache标签来缓存模板片段. 在模板的顶端附近加入{% load cache %}以通知模板存取缓存标签. 模板标签{% cache %}在给定的时间内缓存了块的内容. 它至少需要两个参数: 缓存超时时间(以秒计)和指定缓存片段的名称. 示例: {% load cache %} {% cache 500 sidebar %} .. sidebar .. {% endcache %} 有时你可能想缓存基于片段的动态内容的多份拷贝. 比如,你想为上一个例子的每个用户分别缓存侧边栏.

  • python Django模板的使用方法(图文)

    模版基本介绍模板是一个文本,用于分离文档的表现形式和内容. 模板定义了占位符以及各种用于规范文档该如何显示的各部分基本逻辑(模板标签). 模板通常用于产生HTML,但是Django的模板也能产生任何基于文本格式的文档.来一个项目说明1.建立MyDjangoSite项目具体不多说,参考前面.2.在MyDjangoSite(包含四个文件的)文件夹目录下新建templates文件夹存放模版.3.在刚建立的模版下建模版文件user_info.html 复制代码 代码如下: <html>    <

  • 基于python实现微信模板消息

    我的风格,废话不多说了,直接给大家贴代码了,并在一些难点上给大家附了注释,具体代码如下所示: #!/usr/bin/env python #-*- coding:utf-8 -*- import urllib2,json import datetime,time from config import * import sys reload(sys) sys.setdefaultencoding("utf-8") class WechatPush(): def __init__(self

  • Python实现的简单模板引擎功能示例

    本文实例讲述了Python实现的简单模板引擎功能.分享给大家供大家参考,具体如下: #coding:utf- 8 __author__="sdm" __author_email='sdmzhu3@gmail.com' __date__ ="$2009-8-25 21:04:13$" '' ' pytpl 类似 php的模板类 '' ' import sys import StringIO import os.path import os #模 板的缓存 _tpl_c

随机推荐