Python Jinja2:强大易用的模板引擎

Jinja2是一个基于Python的模板引擎,它的功能类似于PHP的smarty,J2ee的Freemarker和velocity。

模板引擎的应用场景非常广泛,它可以将动态数据与静态模板结合,提高发效率和代码可维护性。

我们平时接触各类网页,邮件通知,甚至一些说明文档,也许都是通过模板引擎生成出来的。

使用模板引擎,还可以辅助我们生成类似的代码,

比如很多ORM框架,就使用了模板引擎来生成大量的model定义代码。

本篇介绍的Jinja2,是目前Python中最流行的模板引擎之一。

1. 安装

通过pip安装:

bash 复制代码
$ pip install Jinja2

安装后可以用如下的代码测试是否安装成功。

bash 复制代码
from jinja2 import Template

# 定义模版
tmpl = Template("hello {{ name }}")

# 根据模版生成最终结果
ret = tmpl.render(name="jinja2")

print(ret)

# 运行结果
hello jinja2

成功安装的话,上面的代码会正常运行并打印出hello jinja2

2. 变量

模板中的变量就是模板中的动态内容,jinja2支持丰富的变量类型。

2.1. 一般变量

一般变量是指基本类型的变量,比如常见的bool型,数值型和字符串类型。

python 复制代码
from jinja2 import Template

tmpl_str = """
布尔型变量:{{ bool_var }}
整数型变量:{{ int_var }}
浮点型变量:{{ float_var }}
字符串变量:{{ str_var }}
"""

def main():
    tmpl = Template(tmpl_str)
    ret = tmpl.render(
        bool_var=True,
        int_var=123,
        float_var=3.14,
        str_var="jinja2 is great!",
    )

    print(ret)


if __name__ == "__main__":
    main()

运行效果:

bash 复制代码
$ python.exe .\main.py

布尔型变量:True
整数型变量:123
浮点型变量:3.14
字符串变量:jinja2 is great!

2.2. 复合变量

复合变量主要指元组列表字典 类型,这些类型在jinja2中也是可以直接识别出来的。

python 复制代码
tmpl_str = """
元组: {{ tuple_var }}
列表: {{ list_var }}
字典: {{ dict_var }}
"""


def main():
    tmpl = Template(tmpl_str)
    ret = tmpl.render(
        tuple_var=(1, "a", 3.14),
        list_var=[1, "a", 3.14],
        dict_var={"key": "name", "value": "jinja2"},
    )

    print(ret)


if __name__ == "__main__":
    main()

运行效果:

bash 复制代码
$ python.exe .\main.py

元组: (1, 'a', 3.14)
列表: [1, 'a', 3.14]
字典: {'key': 'name', 'value': 'jinja2'}

2.3. 对象变量

对象除了有属性,还带有方法,比一般变量和复合变量更具灵活性。

python 复制代码
tmpl_str = """
对象名称: {{ obj_var.name }}
对象动作: {{ obj_var.howl() }}
"""


class Obj:
    def __init__(self, name) -> None:
        self.name = name

    def howl(self):
        return "WO~~~~W"


def main():
    tmpl = Template(tmpl_str)
    obj_var = Obj("Lion")
    ret = tmpl.render(obj_var=obj_var)

    print(ret)


if __name__ == "__main__":
    main()

运行效果:

bash 复制代码
$ python.exe .\main.py

对象名称: Lion   
对象动作: WO~~~~W

3. 控制结构

控制结构帮助我们更加灵活地控制模板的解析和渲染流程,

并能够重复使用常见的行为和代码片段,提高开发效率和代码可维护性。

和编程语言一样,控制结构最常用的就是分支循环

3.1. 分支

分支结构让我们根据业务需求渲染模板的不同部分。

比如,下面的示例演示登录与否的情况下,不同的渲染内容。

python 复制代码
tmpl_str = """
{%- if is_login -%}
你好,{{ login_name }}
{%- else -%}
请先登录!
{%- endif -%}
"""


def main():
    tmpl = Template(tmpl_str)

    # 已登录的情况
    ret = tmpl.render(is_login=True, login_name="jinja2")
    print(ret)

    print("=========================")
    # 未登录的情况
    ret = tmpl.render(is_login=False)
    print(ret)


if __name__ == "__main__":
    main()

运行效果:

bash 复制代码
$ python.exe .\main.py

你好,jinja2
=========================
请先登录!

3.2. 循环

渲染类似内容时,循环结构帮助我们极大减少代码量。

比如,下面的示例中,我们通过循环结构渲染一批学生的成绩。

python 复制代码
tmpl_str = """
学生成绩情况:
====================
{%- for name, score in students.items() %}
姓名: {{ name }}
成绩: {{ score }}分
====================
{%- endfor %}
....
"""


def main():
    tmpl = Template(tmpl_str)

    students = {
        "小红": 100,
        "小张": 76,
        "小李": 68,
        "小黄": 99,
        "小明": 82,
    }

    ret = tmpl.render(students=students)
    print(ret)


if __name__ == "__main__":
    main()

运行效果:

bash 复制代码
$ python.exe .\main.py

学生成绩情况:
====================
姓名: 小红
成绩: 100分
====================
姓名: 小张
成绩: 76分
====================
姓名: 小李
成绩: 68分
====================
姓名: 小黄
成绩: 99分
====================
姓名: 小明
成绩: 82分
====================
....

4. 外部函数

所谓外部函数 ,是指在模板中使用python代码中定义的函数。

也就是把python函数注入到模板中。

这是前几天我尝试生成一些动画代码时,遇到的一个需求。

简单来说,就是在渲染某个变量时,需要根据变量的值,变换不同的内容。

简化后的代码如下:

python 复制代码
tmpl_str = """
直线的颜色:{{ line_color }}
三角形的颜色:{{ triangle_color }}
正方形的颜色:{{ square_color }}
"""


def main():
    tmpl = Template(tmpl_str)

    ret = tmpl.render(
        line_color="g",
        triangle_color="r",
        square_color="b",
    )
    print(ret)


if __name__ == "__main__":
    main()

需要根据颜色的标记 grb等等生成不同的渲染代码。

于是,定义了一个渲染的函数:

python 复制代码
def parse_color(color):
    match color:
        case "r":
            return "<<<code for color RED>>>"
        case "g":
            return "<<<code for color GREEN>>>"
        case "b":
            return "<<<code for color BLUE>>>"
        case _:
            return "<<<code for color WHITE>>>"

为了渲染时能够调用这个函数,只要简单的注册到模板中即可。

python 复制代码
def main():
    tmpl = Template(tmpl_str)
    tmpl.globals["parse_color"] = parse_color
    # .... 其他部分省略

注册到模板之后,就可以直接在模板中使用这个函数了。

python 复制代码
tmpl_str = """
直线的颜色:{{ parse_color(line_color) }}
三角形的颜色:{{ parse_color(triangle_color) }}
正方形的颜色:{{ parse_color(square_color) }}
"""

运行效果:

bash 复制代码
$ python.exe .\main.py

直线的颜色:<<<code for color GREEN>>>
三角形的颜色:<<<code for color RED>>>
正方形的颜色:<<<code for color BLUE>>>

注入函数的这个方式可以避免在模板中写大量的if/else分支代码。

5. 总结

总之,Jinja2是一个功能强大、易于使用和扩展的Python模板引擎,适用于各种需要模板引擎的应用场景。

掌握它的基本功能能够提高我们的开发效率和代码可维护性,使我们能够更专注于实现应用程序的功能和需求。

相关推荐
cuber膜拜42 分钟前
jupyter使用 Token 认证登录
ide·python·jupyter
张登杰踩2 小时前
pytorch2.5实例教程
pytorch·python
codists2 小时前
《CPython Internals》阅读笔记:p353-p355
python
Change is good2 小时前
selenium定位元素的方法
python·xpath定位
Change is good2 小时前
selenium clear()方法清除文本框内容
python·selenium·测试工具
安的列斯凯奇6 小时前
SpringBoot篇 单元测试 理论篇
spring boot·后端·单元测试
架构文摘JGWZ6 小时前
FastJson很快,有什么用?
后端·学习
BinaryBardC6 小时前
Swift语言的网络编程
开发语言·后端·golang
邓熙榆6 小时前
Haskell语言的正则表达式
开发语言·后端·golang
大懒猫软件7 小时前
如何运用python爬虫获取大型资讯类网站文章,并同时导出pdf或word格式文本?
python·深度学习·自然语言处理·网络爬虫