web.py源码分析: 模板(3)

408 查看

前两篇文章主要说明了web.py的模板系统将模板文件处理后得到的结果:__template__()函数。本文主要讲述模板文件是如何变成__template__()函数的。

Render和frender

一般来说,更常用的是Render类,该类会处理整个目录下的模板,还支持缓存和嵌套模板。不过这些其实都和模板本身的解析基本没关系,以后再说明这个类的实现和用途。这里我们使用frender()函数:

这个函数相当简单,只作了一键事情,就是读取模板文件内容,然后交给Template类处理,并且返回一个Template类实例。从这里也可以看出,整个模板的解析,只和Template类有关,frender是来打杂的。

Template类

Template实例的效果

当我们根据一个模板内容创建一个Template类实例t后,我们可以调用该实例,这相当于调用模板对应的__template__()函数,得到的结果是一个TemplateResult实例。

Template实例化过程

Template实例化过程是把模板转换成HTML内容的实质性步骤,不过这个过程比较复杂。但是,概括的来讲,这个过程和Template的__init__()函数中的步骤差不都差不多。

首先把,参数里除了text以外的参数忽略掉,然后来看下对text的处理过程(text就是模板的内容)。整个过程概括的说有如下步骤:

  • 对text作归一化处理:text = Template.normalize_text(text), 主要换行符统一成n,删除BOM字符串,将$替换成$$,这个就是简单的字符串处理。
  • 编译模板得到编译后的Python字节码codecode = self.compile_template(text, filename),code就是之前已经提到过的__template__()函数。
  • 调用父类(BaseTemplate)的__init__()函数:创建__template__()函数的执行环境,并且实现可调用功能。

其他没有说明的代码,暂时都可以忽略,不会影响你理解Template的实例化过程。从上面的步骤可以看出,Template实例化的过程主要有两个:生成__template__()函数的代码并编译,以及创建__template__()函数的执行环境。

生成__template__()函数的代码

这个是模板生成过程中最长最复杂的一段,会应用到Python的token分析功能以及动态编译功能。还记得第一篇里,我们搭建实验环境的时候,修改了web.py源码,在一个地方插入了一行打印语句么?没错,就是这个compile_template()函数,我们现在来看看它是如何生成__template__()函数的代码的。