最常见的一个以文字为主的任务是在 web 应用程序。任何 web 应用程序的一个重要工序是生成用于浏览器显示的 HTML。 很少有 HTML 页面是完全静态的:它们至少包含少量的动态数据,比如用户名。通常,它们包含大量的动态数据:产品列表、好友的新闻更新等等。
这里,用户的名字将是动态的,就像产品的名称和价格一样。甚至产品的数量也不是固定不变的:有时可能会有更多或更少的产品展示出来。
构造这个 HTML 的一种方法是在我们的代码中将字符串常量们合并到一起来生成页面。动态数据将插入以替换某些字符串。我们的一些动态数据是重复的,就像我们的产品列表一样。 这意味着我们将会有大量重复的 HTML,因此这些内容必须单独处理,并与页面的其他部分合并。
比如,我们的 demo 页面像这样:
零基础小白到大神之路,欢迎加裙 四七四五三四九五一,群里有免费python课程,还有大量干货哦
这是可行的,但是有点乱。HTML 是嵌入在我们的代码中的多个字符串常量。页面的逻辑很难看到,因为静态文本被拆分为独立的部分。如何格式化数据的细节隐藏在 Python 代码中。为了修改 HTML 页面,我们的前端设计人员需要能够编辑 Python 代码。想象一下,如果页面是10(或者100)倍的复杂,代码会是什么样子。它很快就会变得无法维护。
模板
当模板被呈现时,模板中可用的数据将提供给上下文。稍后将进行更详细的讨论。
模板引擎通常使用简化的、轻松的语法来访问数据中的元素。在 Python 中,这些表达式有不同的效果:
管理动态上下文,数据的来源
执行逻辑元素
实现点访问和筛选执行
从解析阶段传递什么到呈现阶段是关键。
解析可以提供什么?有两种选择:我们称它们为解释和编译。
在解释模型中,解析生成一个表示模板结构的数据结构。呈现阶段将根据所找到的指令对数据结构进行处理,并将结果文本组合起来。Django 模板引擎使用这种方法。
在编译模型中,解析生成某种形式的可直接执行的代码。呈现阶段执行该代码,生成结果。Jinja2 和 Mako 是使用编译方法的模板引擎的两个例子。
我们的引擎的实现使用编译模型:我们将模板编译成 Python 代码。当它运行时,组装成结果。 模板被编译成 Python 代码,程序将运行得更快,因为即使编译过程稍微复杂一些,但它只需要运行一次。 将模板编译为 Python 要稍微复杂一些,但它并没有您想象的那么糟糕。而且,正如任何开发人员都能告诉你的那样,编写一个会编写程序的程序比编写程序要有趣得多!
几点说明:
通过缓存了一些函数到局部变量来对代码进行了优化(比如 append_result = result.append 等)
点符号操作被转化成了
do_dots
函数
逻辑代码被转化成了 python 代码和循环
编写模板引擎
模板类
可以使用模板的文本构造了 Templite 对象,然后您可以使用它来呈现一个特定的上下文,即数据字典:
CodeBuilder
引擎中的大部分工作是解析模板并生成 Python 代码。为了帮助生成 Python,我们创建了 CodeBuilder 类,它帮我们添加代码行,管理缩进,最后从编译的 Python 中给出结果。
CodeBuilder 对象保存了一个字符串列表,这些字符串将一起作为最终的 Python 代码。它需要的另一个状态是当前的缩进级别:
实现模板类
编译
将模板编译成 Python 函数的所有工作都发生在 Templite 构造函数中。首先,传入的上下文被保存:
请点击此处输入图片描述
将文本拆分为这样的 tokens 之后,我们可以对这些 tokens 进行循环,并依次处理它们。根据他们的类型划分,我们可以分别处理每种类型。 编译代码是对这些 tokens 的循环:
表达式
现在让我们来仔细的分析下表达式的编译过程。
我们的表达式可以简单到只有一个变量名:
{}
也可以很复杂:
{}
零基础小白到大神之路,欢迎加裙 四七四五三四九五一,群里有免费python课程,还有大量干货哦
领取专属 10元无门槛券
私享最新 技术干货