本文实例讲述了Python实现的简单模板引擎功能。分享给大家供大家参考,具体如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
#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_cache = {} class Pytpl: def __init__( self ,tpl_path = './' ): self .tpl_path = tpl_path self .data = {} self .output = StringIO.StringIO() pass def set ( self ,name,value): ' ' ' 设 置模板变量 ' ' ' self .data[name] = value; pass def get( self ,name): ' ' ' 得 到模板变量 ' ' ' t = {} return t.get(name, '' ) pass def tpl( self ,tplname): ' ' ' 渲 染模板 ' ' ' f = self .tpl_path + tplname if not os.path.exists(f): raise Exception( 'tpl:[%s] is not exists' % f) mtime = os.stat(f).st_mtime if not _tpl_cache.has_key(f) or _tpl_cache[f][ 'time' ]<mtime: src_code = self .__compile__( open (f).read()) try : t = open (f + '.py' , 'w' ) t.write(src_code) t.close() except : pass py_code = compile (src_code, f + '.py' , 'exec' ) _tpl_cache[f] = { 'code' :py_code, 'time' :mtime} else : py_code = _tpl_cache[f][ 'code' ] exec (py_code, { 'self' : self }, self .data) return self .output.getvalue() def execute( self ,code,data,tplname): ' ' ' 执 行这个模板 ' ' ' py_file_name = tplname + '.py' f = open (py_file_name, 'w' ) f.write(code) f.close() execfile (py_file_name, { 'self' : self }, data) def __compile__ ( self ,code): ' ' ' 编 译模板 查找 <?标记 ' ' ' tlen = len (code); flag_start = '<?' flag_end = '?>' # 默认普通标记 status = 0 i = 0 #分块 标记 pos_end = 0 pos_start = 0 #缩 进 global indent indent = 0 py_code = [] def place_t_code(c,t_indent): ' ' ' 基 本的代码处理 ' ' ' global indent if (c[ 0 ] = = '=' ): return ( ' ' * 4 * indent) + 'echo ( /' % s / ' % (' + c[ 1 :] + '))' lines = c.split( "/n" ) t = [] for i in lines: indent2 = indent tmp = i.strip( " /n/r" ) c = tmp[ len (tmp) - 1 : len (tmp)] # 判定最后一个字符 if (c = = '{' ): indent + = 1 tmp = tmp[ 0 : len (tmp) - 1 ] + ":" elif (c = = '}' ): indent - = 1 tmp = tmp[ 0 : len (tmp) - 1 ] t.append(( ' ' * 4 * indent2) + tmp ) return "/n" .join(t) while 1 : if i> = tlen: break c = code[i]; if status = = 0 : # 编译加速 pos_start = code.find(flag_start,pos_end); if (pos_start> - 1 ): s = code[pos_end:pos_start] t_code = 'echo ( ' + repr (s) + ')' t_code = ' ' * indent * 4 + t_code if s: py_code.append(t_code) i = pos_start last_pos = i # 进入代码状态 status = 1 continue else : # 没有没有找到 pos_start = tlen t_code = 'echo ( ' + repr (code[pos_end:pos_start]) + ' ) ' t_code = ' ' * indent * 4 + t_code py_code.append(t_code) break if status = = 1 : # 查找结束标记 pos_end = code.find(flag_end,i) if (pos_end> - 1 ): # 需要跳过<? 这个标记 t_code = place_t_code(code[pos_start + 2 :pos_end],indent) # 跳过?>结束标记 pos_end + = 2 py_code.append(t_code) else : # 没查找到直接结束 pos_end = tlen # 需要跳过<? 这个标记 t_code = place_t_code(code[pos_start + 2 :pos_end],indent) py_code.append(t_code) break status = 0 i = pos_end pass i + = 1 py_code_str = "#coding:utf-8/nimport sys;global echo;echo=self.output.write/n" py_code_str + = "/n" .join(py_code) py_code_str = py_code_str.replace( "/t" , " " ) return py_code_str def test(): tpl = Pytpl( './' ); tpl. set ( 'title' , '标题3' ) print tpl.tpl( 'test.html' ) pass if __name__ = = "__main__" : test() |
希望本文所述对大家Python程序设计有所帮助。
原文链接:http://blog.csdn.net/m190481164/article/details/5611713