试读webpy template源码
更新日期:
这几天花了点时间读了下web.py的template代码,只是大概的过了下。主要想了解下Python中AST编译相关的模块使用方法。
先看个webpy template使用方法,来自其cookbook. 首先是template内容的html, 置于./templates/hello.html
|
|
在代码里初始化render, 传递文件夹名为参数,然后就可以调用和模板同名的方法了,生成的html以字符串返回。
|
|
web.py template的语法格式同样参考其cookbook,变量赋值或语句都以$开始;$if/$for/$while都需要单独一行,内容行首遵循python的缩进格式。template内容是一行行处理的, 生成nodelist,转换成python代码,然后再调用python 编译服务。
看代码当然是从github开始了, template 相关的代码在文件 webpy / web / template.py
. template的初始化是从class Render
开始,由render._load_template
,模板类是class BaseTemplate
和class Template
。模板的解析工作由class Parser
进行, 解析后生成的node类有DefwithNode, TextNode, ExpressionNode, AssignmentNode, LineNode, BlockNode, ForNode, CodeNode, StatementNode, IfNode, ElseNode, ElifNode, DefNode, VarNode, SuiteNode。每个node类都定义有emit()
用于生成对应的python代码。
将template转成python代码
Template在init()调用self.compile_template将template转成一个python函数的代码,再调用builtin方法compile()和exec()编译,当需要即执行新生成的函数。
将template转成python由Template.generate_code完成。这里略过Parse的细节。下面代码演示生成的python代码。
以下为template test.html的内容,添加了一个if/else块:
生成的python代码:
编译python函数
生成代表python function的字符串后,还需要compile()和exec()才能生成可调用的对象。
在前边生成的代码,可以看到有创建外部类的对象,ForLoop(),TemplateResult()和escape_, 需要在comile时导入。
生成的函数对象可以由env[‘template‘]获得。最后打印出的结果如下: