代码翻译模板-程序代码翻译模板

日期:2023-03-11 12:39:36 / 人气: 573 / 发布者:成都翻译公司

我们之前的程序主要是python代码,有一些HTML代码嵌入python逻辑中。既然我们用python来实现我们的模板引擎,一些python的概念会出现在我们的语法中。我们实现的引擎使用编译方法:我们将模板编译为python代码。我们的引擎将编译这个模板为python代码。每个模板都被转换为一个render_function函数,其接受一个叫做context的数据字典。

500行以内是一系列非常经典且相对较短的python文章。每章代码不超过500行,但实现了一些强大的功能。是业内大佬写的,有很大的学习价值。适合新手了解基本概念,也适合进阶python。

来源文章

源代码

其他一些开源翻译文章

介绍

在一些编程任务中代码模板翻译,逻辑很少,但文本很多。对于这些任务,我们希望有更好的工具来解决这些基于文本的问题。模板引擎就是这样一个工具。在本文中,我们构建了一个简单的模板引擎。

Web 应用程序是基于文本的任务的*常见示例。任何 Web 应用程序中的一个重要阶段是生成 HTML 并将其交付给浏览器。只有少数 HTML 页面是纯静态的,它们基本上至少包含少量动态数据,例如用户名。通常它们包含更多动态数据:产品列表、来自朋友的新消息等。

同时,每个 HTML 页面都包含大量静态文本。而且这些页面非常大,包含数万字节的文本。那么,Web 应用程序开发人员面临一个问题:如何生成大量的静态和动态数据是*好的?另外,静态文本内容其实是HTML标记语言,由团队其他成员-前端设计师创建,这种生成方式*好让他们熟悉。

为了说明这一点,我们假设我们想要生成这个极简的 HTML:

Welcome, Charlie!Products:Apple: $1.00Fig: $1.50Pomegranate: $3.25

在这里,用户名将是动态的代码模板翻译,产品的名称和价格也将是动态的。甚至产品数量也不固定,因为库存在波动。

生成 HTML 的一种方法是在我们的代码中添加字符串常量,然后将它们与动态数据组合以生成页面。动态数据将以某种形式的字符串替换插入。我们的一些动态数据是重复的,比如我们的产品列表,这意味着我们有一批重复的 HTML 块。所以我们单独对待它,并与其他部分结合起来。

以上述方式生成的页面将如下所示:

# The main HTML for the whole page.
PAGE_HTML = """Welcome, {name}!Products:{products}"""
# The HTML for each product displayed.
PRODUCT_HTML = "{prodname}: {price}"
def make_page(username, products):
    product_html = ""
    for prodname, price in products:
        product_html += PRODUCT_HTML.format(
            prodname=prodname, price=format_price(price))
    html = PAGE_HTML.format(name=username, products=product_html)
    return html

它有效,但它给我们增加了很多麻烦。HTML 代码嵌入在应用程序代码中的多个字符串常量中。页面的逻辑很不清楚,因为静态内容被分成了几块。Python 代码中丢失了有关如何格式化数据的详细信息。为了修改HTML页面,我们的前端工程师必须学会修改python代码。如果页面复杂十倍或一百倍,这种做法会让人感到无所适从。

模板

使用模板生成 HTML 页面是一种更好的方法。HTML 页面是作为模板创建的,这意味着该文件主要是静态 HTML,其中嵌入了由特殊符号表示的动态数据片段。上面的*小页面变成了这样的模板:

Welcome, {{user_name}}!Products:{% for product in product_list %}{{ product.name }}:
        {{ product.price|format_price }}{% endfor %}

此时,重点是 HTML 文本,仅嵌入了一些逻辑结构。将这种以文本为中心的方法与之前以逻辑为中心的代码进行比较。我们之前的程序主要是python代码,python逻辑中嵌入了一些HTML代码。在这里,它们中的大多数是静态 HTML 标记语言。

模板的多静态风格与大多数编程语言的工作方式相反。例如,python 的大多数源文件都是可执行代码。如果您需要文字静态文本,请将其嵌入到字符串中:

def hello():
    print("Hello, world!")
hello()

当python读取这个源文件时,它的翻译类似于def hello():这样的语句就是一条要执行的指令。print("Hello, world!") 中的双引号表示文本只是文字。这是大多数编程语言的工作方式:动态是中流砥柱,而指令中嵌入了少量静态片段。静态部分用引号标记。

模板语言正好相反:它主要是静态文字文本,同时使用特殊符号来表示可执行文件的动态部分。

Welcome, {{user_name}}!

此处的文本字面出现在生成的 HTML 页面中。直到 {{}} 表示里面的内容是动态模式,里面的变量才会在输出中被替换。

Python的"foo = {foo}!".format(foo=17)等字符串格式化函数是小语言的典型例子。这种语言用来按字面意思和要插入的数据创建文本。模板将这个想法扩展到包括条件和循环结构,唯一的区别是扩展的程度。

这些文件被称为模板,因为它们用于生成许多具有相似结构和不同细节的页面。

为了在我们的程序中使用 HTML 模板,我们需要一个模板引擎:一个接收参数作为静态模板(包含页面的结构和静态内容)和动态上下文(提供嵌入在模板中的动态数据)的函数。这个模板引擎结合了模板和上下文来生成一个纯 HTML 字符串。模板引擎的任务是翻译模板并用动态数据替换动态片段。

顺便说一下,模板引擎不是针对 HTML 的,它可以用来生成任何文本结果。例如,它们还用于生成纯文本电子邮件。但是它们通常在HTML中使用,偶尔会有一些HTML特有的功能,比如转义(escaping),这使得在HTML中插入值成为可能,而不必担心HTML中是否存在特殊字符。

支持的语法

模板引擎支持的语法不同。我们的模板语法基于流行的 Web 框架 Django。由于我们使用python来实现我们的模板引擎,所以我们的语法中会出现一些python的概念。我们已经在本章顶部的简约模板中看到了部分语法。下面是我们将实现的语法的快速总结。

上下文中的数据使用双花括号插入:

Welcome, {{user_name}}!

呈现模板时,模板中可用的数据由上下文提供。以后再说。

模板引擎通常使用简化和宽松的语法来提供对数据元素的访问。在python中,这些表达式有不同的效果:

dict["key"]
obj.attr
obj.method()

在我们的模板语法中,所有这些操作都用点表示:

dict.key
obj.attr
obj.method

点将访问对象的属性或字典的值,如果结果值是可调用的,它将被自动调用。这与 python 代码不同,其中这些操作具有不同的语法。这导致了一个简单的模板语法:

The price is: {{product.price}}, with a {{product.discount}}% discount.

您还可以使用称为过滤器的函数来修改值。过滤器由竖线(管道字符)调用:

Short name: {{story.subject|slugify|lower}}

如果条件语句可用,构建一个有趣的网站通常至少需要一些决定:

{% if user.is_logged_in %}Welcome, {{ user.name }}!{% endif %}

循环让我们在页面中包含一组数据:

Products:{% for product in product_list %}{{ product.name }}: {{ product.price|format_price }}{% endfor %}

就像其他编程语言一样,条件和循环语句可以嵌套以构建复杂的逻辑结构。

*后,让我们将文档添加到模板中,注释出现在花括号和井号之间:

{# This is the best template ever! #}

执行

模板引擎有两个主要阶段:解析模板,然后渲染模板。

渲染模板具体包括:

从解析阶段传递到渲染阶段的内容是问题的关键。解析为渲染产生什么?有两个主要选项,我们称之为解释和编译,使用与其他语言实现相关的术语。

在解释模型中,分析产生表示模板结构的数据结构。渲染阶段遍历该数据结构并根据找到的指令组合结果文本。一个真实的例子是使用这种方法的 Django 模板引擎。

在编译模型中,解析产生某种形式的直接可执行代码。代码在渲染阶段执行,并产生结果。Jinja2 和 Mako 都是使用编译方式的模板引擎。

我们实现的引擎采用的是编译方式:我们将模板编译成python代码。执行时,代码会组合结果。这里描述的模板引擎*初是作为coverage.py 的一部分编写的,用于生成HTML 报告。在coverage.py中,只有几个模板,并且被反复使用,生成了很多文件。一般来说,如果将模板编译成python代码,程序运行速度会更快,因为即使编译过程更复杂,也只需要运行一次,编译后的代码执行多次,这比解释的要多得多一种数据结构。快多了。

将模板编译成 python 代码有点复杂,但没有你想象的那么糟糕。另外,写一个能写代码的程序,比写程序本身有趣多了!我们的模板编译器是代码生成常用技术的一个小例子。代码生成技术构成了许多强大而灵活的工具的基础,包括编程语言编译器。代码生成可能会变得非常复杂,但它是一种值得拥有的有用技术。

如果模板一次只使用几次,这样的模板应用程序可能倾向于解释该方法。从长远来看,将模板编译成 python 代码的成本要贵一些。总的来说,更简单的解释过程可能会更好。

编译为 Python

在拿到模板引擎的代码之前,我们先来看看它生成的代码。解析阶段将模板转换为 Python 函数。再次使用我们的小模板:

Welcome, {{user_name}}!Products:{% for product in product_list %}{{ product.name }}:
        {{ product.price|format_price }}{% endfor %}

我们的引擎会将此模板编译为 python 代码。python 代码的结果看起来不寻常,因为我们选择了一些快捷方式来生成轻量级和更快的代码。为了便于阅读,以下 Python 代码已稍微重新格式化:

def render_function(context, do_dots):
    c_user_name = context['user_name']
    c_product_list = context['product_list']
    c_format_price = context['format_price']
    result = []
    append_result = result.append
    extend_result = result.extend
    to_str = str
    extend_result([
        'Welcome, ',
        to_str(c_user_name),
        '!Products:'
    ])
    for c_product in c_product_list:
        extend_result([
            '',
            to_str(do_dots(c_product, 'name')),
            ':
        ',
            to_str(c_format_price(do_dots(c_product, 'price'))),
            ''
        ])
    append_result('')
    return ''.join(result)

每个模板都被转换成一个 render_function 函数,它接受一个名为 context 的数据字典。函数体首先将上下文字典中的数据解包为局部变量,因为重复使用数据会更快。所有的上下文数据都以加c_前缀的形式变成局部变量,这样我们就可以自由地使用局部变量名而不必担心命名冲突。

模板的结果将是一个字符串。从部分构建字符串的*快方法是创建一个字符串列表,然后将它们组合在一起。结果是一个字符串列表。因为我们将向这个列表添加一个字符串,所以我们捕获了它的 append 和 extend 方法并将其分配给局部变量 result_append 和 result_extend。创建的*后一个局部变量是内置方法 str - to_str 的简写。

这些形式的快捷键很不寻常。让我们更仔细地看:在python中,诸如result.append("hello")之类的对象调用的方法分两步执行。首先从result对象中获取append属性,然后将获取到的值作为函数调用,传递参数“hello”给它。虽然我们习惯于看到这些步骤一起执行,但它们实际上是分开的。如果您存储第一步的结果,那么您将对存储的结果执行第二步。所以下面的两个代码片段做同样的事情:

# The way we're used to seeing it:
result.append("hello")
# But this works the same:
append_result = result.append
append_result("hello")

在模板引擎代码中,我们采用了这种分离方式,这样无论第二步做多少次,第一步都只需要做一次。这为我们节省了少量时间,因为它避免了花时间查找对象的 append 属性。

这是微优化的一个例子:一种不寻常的编码技术使我们能够获得速度的小幅提升。微优化可能会使代码可读性较差或更容易混淆,因此只有使用被证明是性能瓶颈的代码才是合理的。开发者对于什么微优化是合理的存在分歧,一些新手会过度使用它。这里的优化仅在时间测试表明它们提高了性能时才添加,即使是很小的改进。微优化很有启发性,因为它们使用了 Python 的一些奇怪的方面,但不要在您自己的代码中过度使用它。

str 的快捷方式也是一个微优化。python 中的变量可以是函数局部或模块全局或 python 内置。查找局部变量名称比查找全局或内置名称更快。我们习惯于 str 是一个始终可用的内置函数,但是每次使用时,python 仍然必须查找变量名。将它放在局部变量中可以为我们节省少量时间,因为局部变量比内置变量快。

一旦定义了这些快捷键,以下是被认为是从我们的特定模板生成的python代码。字符串将使用 append_result 或 extend_result 快捷键添加到结果列表中。选择上一个还是下一个取决于我们是只添加一个字符串还是多个字符串。模板中的文本变成了一个简单的字符串。

同时使用 append 和 extend 方法会增加复杂性,但请记住,我们的目标是*快地执行模板。对项目使用扩展意味着创建该项目的新列表,以便我们可以将其传递给扩展。

{{...}} 中的表达式将被计算,转换为字符串,并添加到结果中。表达式中的点会被传递给渲染函数的do_dots函数处理,认为打点表达式的含义取决于上下文中的数据形式:可能是属性访问、子项获取,也可能是调用。

{% if ... %} 和 {% for ... %} 的逻辑结构被转化为 python 条件语句和循环。{% if/for ... %} 标签中的表达式将成为 if/for 语句中的表达式,然后 {% end ... %} 标签之前的内容将成为语句的主体。

相关阅读Relate

  • 法国签证营业执照翻译件模板 你与申根签证只有一条推送的距离
  • 江苏省增值税发票翻译模板 江苏税务局出口货物退(免)税申报管理系统软件
  • 肄业证书翻译模板 复旦大学学生学业证明文书管理细则(试行)
  • 四级英语作文模板带翻译 大学英语四级翻译模拟训练及答案
  • 社会某信用代码证翻译模板 js验证某社会信用代码,某社会信用代码 验证js,js+验证+社会信用代码证
  • 美国移民证件翻译模板 日语签证翻译聊聊身份证翻译模板
  • 翻译软件模板 人类史上*实用的的文档快速翻译指南
  • 江苏省增值税发票翻译模板 江苏出口货物退(免)税申报管理服务平台
  • 瑞士签证房产证翻译件模板 瑞士探亲签证—就读子女
  • 日语户口本翻译模板 户口本翻译价格_户口本翻译一般多少钱?
  • 代码翻译模板-程序代码翻译模板 www.chinazxzy.com/fymb/3876.html
    
    本站部分内容和图片来源于网络用户和读者投稿,不确定投稿用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的权利,请联系:chinazxzy@163.com,及时删除。
    Go To Top 回顶部
    • 扫一扫,微信在线