У меня были хорошие голоса, когда отвечал на дубликат этого же вопроса .
Мой ответ был:
Jinja2 .
Хороший синтаксис , хороший возможности настройки .
Хорошо интегрируется. Может быть изолированным, так что вам не нужно полностью доверять авторам шаблонов. (Мако не может).
Это также довольно быстро, с бонусом компиляции вашего шаблона для байт-кода и кэширования его, как показано ниже:
>>> import jinja2
>>> print jinja2.Environment().compile('{% for row in data %}{{ row.name | upper }}{% endfor %}', raw=True)
from __future__ import division
from jinja2.runtime import LoopContext, Context, TemplateReference, Macro, Markup, TemplateRuntimeError, missing, concat, escape, markup_join, unicode_join
name = None
def root(context, environment=environment):
l_data = context.resolve('data')
t_1 = environment.filters['upper']
if 0: yield None
for l_row in l_data:
if 0: yield None
yield unicode(t_1(environment.getattr(l_row, 'name')))
blocks = {}
debug_info = '1=9'
Этот код был сгенерирован на лету Jinja2. Конечно, компилятор оптимизирует его (например, удаляя if 0: yield None
)