bottle.py中的SimpleTemplate
import re
class SimpleTemplate(object):
re_block = re.compile(r'^\s*%\s*((if|elif|else|try|except|finally|for|while|with).*:)\s*$')
re_end = re.compile(r'^\s*%\s*end(.*?)\s*$')
re_code = re.compile(r'^\s*%\s*(.*?)\s*$')
re_inc = re.compile(r'\{\{(.*?)\}\}')
def __init__(self, template):
self.code = "\n".join(self.compile(template))
self.co = compile(self.code, '<string>', 'exec')
def render(self, **args):
''' Returns the rendered template using keyword arguments as local variables. '''
args['stdout'] = []
args['__builtins__'] = __builtins__
eval(self.co, {}, args) # 执行Python代码
return ''.join(args['stdout'])
def compile(self, template):
'''
将模板转换为可执行的Python代码
'''
def code_str(level, line, value): # 可直接输出的字符串
value = "".join(value)
value = value.replace("'","\'").replace('\\','\\\\')
return ' '*level + "stdout.append(r'''%s''')" % value
def code_print(level, line, value): # {{...}}中的内容,需要执行代码后取得字符串再输出
return ' '*level + "stdout.append(str(%s)) # Line: %d" % (value.strip(), line)
def code_raw(level, line, value): # 以%开头,需要作为代码执行
return ' '*level + value.strip() + ' # Line: %d' % line
level = 0 # 缩进深度
ln = 0 # 行号(无具体作用,方便定位问题)
sbuffer = [] # 模板中的普通字符串
for line in template.splitlines(True):
ln += 1
# Line with block starting code
m = self.re_block.match(line)
if m:
if sbuffer:
yield code_str(level, ln, sbuffer)
sbuffer = []
if m.group(2).strip().lower() in ('elif','else','except','finally'):
if level == 0:
raise TemplateError('Unexpected end of block in line %d' % ln)
level -= 1
yield code_raw(level, ln, m.group(1).strip())
level += 1
continue
# Line with % end marker
m = self.re_end.match(line)
if m:
if sbuffer:
yield code_str(level, ln, sbuffer)
sbuffer = []
if level == 0:
raise TemplateError('Unexpected end of block in line %d' % ln)
level -= 1
continue
# Line with % marker
m = self.re_code.match(line)
if m:
yield code_raw(level, ln, m.group(1).strip())
continue
# Line with inline code
lasts = 0
for m in self.re_inc.finditer(line):
sbuffer.append(line[lasts:m.start(0)])
yield code_str(level, ln, sbuffer)
sbuffer = []
lasts = m.end(0)
yield code_print(level, ln, m.group(1))
if lasts:
sbuffer.append(line[lasts:])
continue
# Stupid line
sbuffer.append(line)
if sbuffer:
yield code_str(level, ln, sbuffer)
if __name__ == "__main__":
# 简单替换
t1 = SimpleTemplate('Hello {{name}}!')
print t1.render(name='<b>World</b>')
# 嵌入python语句(必须返回str)
t2 = SimpleTemplate('Hello {{name.title() if name else "stranger"}}!')
print t2.render(name=None)
print t2.render(name="tuzkee")
# %执行Python语句
tmp3="""
%if name:
Hi <b>{{name}}</b>
%else:
<i>Hello stranger</i>
%end"""
t3 = SimpleTemplate(tmp3)
print t3.render(name=None)
tmp4="""
%for i in range(3):
%for j in range(3):
{{"%s:%s"%(i,j)}}
%end
%end"""
t4 = SimpleTemplate(tmp4)
print t4.render()
bottle.py中的SimpleTemplate的更多相关文章
- bottle.py中的路由搜索优化
# Now search regexp routes # ROUTES_REGEXP是一个字典,键是请求方法,值是[路由, 处理函数]的列表 # 例如:{"GET", [[路由1, ...
- bottle.py中的路由解析代码
# Routing def compile_route(route): """ Compiles a route string and returns a precomp ...
- Python的Bottle框架中实现最基本的get和post的方法的教程
这篇文章主要介绍了Python的Bottle框架中实现最基本的get和post的方法的教程,Bottle框架在Python开发者中的人气很高,需要的朋友可以参考下 1.GET方式: # -*- cod ...
- python调用py中rar的路径问题。
1.python调用py,在py中的os.getcwd()获取的不是py的路径,可以通过os.path.split(os.path.realpath(__file__))[0]来获取py的路径. 2. ...
- Django 中 如何使用 settings.py 中的常量
在用django 框架开发 python web 程序的时候 , 在模板页面经常会用到 settings.py 中设置的常量,比如MEDIA_URL, 我尝试过在模板页面用类似如下的方式 程序代码 { ...
- 配置python+mod_wsgi+apache 时 在浏览器中访问服务器时报错:Invalid HTTP_HOST header: 'XXXXX'. You may need to add u'XXXXX' to ALLOWED_HOSTS,在setting.py中添加‘*”无效的原因
配置python+mod_wsgi+apache 时 在浏览器中访问服务器时报错:Invalid HTTP_HOST header: 'XXXXX'. You may need to add u'XX ...
- [django]urls.py 中重定向
Django 1.5 有时候需要对一个链接直接重定向,比如首页啥的重定向到一个内容页等等,在views.py 中可以设定,如果没有参数啥的在urls.py 中设定更加方面 from django.vi ...
- 不在models.py中的models
概述 如何让你定义的model不在models.py中 在app的models目录中的models 你新建一个app后这个models.py就会自动建立,里面只有几行代码.那么如果是一个中大型项目,每 ...
- javascript中的值如何传递到django下的views.py中或者数据库中?
用Ajax,Ajax有很多种写法,包括JQuery和JS,这里贴一个用JQuery写的最通用的Ajax,POST方法传递JSON格式数据: $.ajax({ url: "your url&q ...
随机推荐
- 方程的解_NOI导刊2010提高
方程的解 给定x,求\(a_1+a_2+...+a_k=x^x\ mod\ 1000\)的正整数解解的组数,对于100%的数据,k≤100,x≤2^31-1. 解 显然x是可以快速幂得到答案的,而该问 ...
- C(n,m)排列组合算法
主要解决C(n,m)问题 static class Extension { public static IList<IList<T>> GetGroup<T>(th ...
- windows 定时备份linux 上oracle 数据库
1.bat 脚本 exp root/root@10.0.0.0:1521/feiye grants=y owner=root file='E:\code\environment\mysqlBackDa ...
- 使用querybuilder做忽略大小写查询的例子
自定义Predicate: import com.day.cq.search.Predicate; import com.day.cq.search.eval.AbstractPredicateEva ...
- Java 使用jxl对Excel进行操作
一个作业需要对excel数据进行离散化,想起好像可以用java对excel数据进行处理,因此学习使用, 在网上也有很多人对这个内容解释,但是还是觉得有些杂,就自己整理了一些别人写的内容. /***** ...
- max of 直线划平面
在一个无限延伸平面上有一个圆和n条直线,这些直线中每一条都在一个圆内,并且同其他所有的直线相交,假设没有3条直线相交于一点,试问这些直线最多将圆分成多少区域. Input 第一行包含一个整数T,(0& ...
- IIS Service Unavailable HTTP Error 503. The service is unavailable.
IIS突然报了上图这样一个错误,很意外,这问题的来源百度上有多个版本,处理的办法几乎都是一样的,你可以通过下边这个链接去查看, https://www.cnblogs.com/fri-yu/p/407 ...
- python数据结构与算法之问题求解
懂得计算机的童鞋应该都知道,一条计算机程序由数据结构跟算法两大部分组成.所以,其实不管你使用哪种计算机语言编写程序,最终这两部分才是一个程序设计的核心.所以,一个不懂得数据结构与算法的程序员不是一个好 ...
- springboot学习小记
思维导图:https://www.edrawsoft.cn/viewer/public/s/72a06689197636 1.springboot是一个快速整合第三方框架,简化XML配置完全采用注解化 ...
- python正则表达式补充
import re origin= "hello alex bcd alex 1ge alex acd 19" r=re.match("(?P<n1>h)(? ...