= 用python做静态文件生成程序 = 我想,给大家介绍python,并不是一定会再工作中用到,毕竟实际应用起来还是要考虑许多非技术的问题。主要是想让大家了解一点新东西吧。大家可以先看下这个,有兴趣的话分享的时候再介绍一些python的基本情况。python本身以及下面代码涉及到的库都是跨平台的,大家有兴趣的话可以直接在windows上试验了。以后要是真的投入实际应用,也可以在windows上开发调试,然后再拷到服务器上去执行。 生成静态文件的逻辑其实不复杂,无非加载数据,渲染模板。加载数据的时候需要做一些转换,过滤,分类,排序,分页等。渲染模板的时候也会有一些简单的逻辑。说起来很简单,但用c++实现起来却需要一大坨代码。用python可以少敲很多代码。 比如说生成全部歌手的页面。自然语言描述如下: {{{ 连接数据库 执行sql语句 select * from music.t_singer; 获取歌手数据 执行sql语句 select * from music.t_track; 获取歌曲数据 加载模板 渲染模板 写文件 }}} 现在来看下python代码: {{{#!python # 导入 mysql 的库和模板类 import MySQLdb as dbapi from mako.template import Template # 连接数据库 connection = dbapi.connect(host="ip", port=port, user="...", password="...",database="...") cursor = connection.cursor(dbapi.DictCursor) #默认fetchall返回的是tuple,类似列表,也就是只能用 0,1,2,3 这样访问,传递这个参数会可以返回 字段名:value 这样哈希表 # 加载数据 cursor.execute("select * from music.t_singer;") singerlist = cursor.fetchall() cursor.execute("select * from music.t_track") songlist = cursor.fetchall() # 转换数据 # 把 songlist 转换成以 singer id 为 key 的哈希表(c++叫map,python叫dict字典,javascript叫对象)方便查找。 songmap = defaultdict(list) for song in songlist: songmap[song['Fsinger_id']].append(song) #加载模板 template = Template(filename="模板文件路径/singer_tpl.html") for singer in singerlist: # 循环渲染模板 content = template.render(singer=singer, songlist = songmap[singer['Fsinger_id']]]) file = open('目标路径/singer_%d.html' % singer.id, 'w') #写文件 file.write(content) file.close() cursor.close() connection.close() }}} 关于错误处理,一般如果出错应该直接推出程序的就没必要去捕捉了,因为退出的时候,python本身会输出详细的异常信息,出错位置,和完整的backtrace。 "Errors should never pass silently. Unless explicitly silenced." -- [[http://www.python.org/dev/peps/pep-0020/|zen of python]] 大家也可以看到渲染模板的时候只传一个 {{{singer}}} 对象进去,实际上在模板里面也是可以放一些简单的程序逻辑的,比如循环,比如获取对象的属性等,这也大大降低了主程序的复杂性。 另外下面的模板利用了模板继承的特性,可以把页面通用的部分(比如导航栏)做成一个父模板,子模板直接继承,同时又可以重写一部分父模板的内容(比如修改title)。 父模板({{{base_tpl.html}}}): {{{