首页
学习
活动
专区
圈层
工具
发布
50 篇文章
1
【原创佳作】介绍Pandas实战中一些高端玩法
2
pandas 如何实现 excel 中的汇总行?
3
pandas多级索引的骚操作!
4
40000字 Matplotlib 实操干货,真的全!
5
利用Python搞定女朋友的小情绪~
6
Python 绘制惊艳的瀑布图
7
6种方式创建多层索引
8
Python 进阶指南(编程轻松进阶):三、使用 Black 工具来格式化代码
9
数据科学 IPython 笔记本 9.6 聚合:最小、最大和之间的任何东西
10
精通 Pandas 探索性分析:1~4 全
11
高手系列!数据科学家私藏pandas高阶用法大全 ⛵
12
总结了67个pandas函数,完美解决数据处理,拿来即用!
13
PyAutoGUI,一个Python办公自动化利器!
14
解放双手|利用 PyAutoGUI 快速构建自动化操作脚本
15
Python中内置数据库!SQLite使用指南! ⛵
16
数据分析索引总结(中)Pandas多级索引
17
数据分析索引总结(下)Pandas索引技巧
18
数据分析索引总结(上)Pandas单级索引
19
网友需求系列01-Python-matplotlib定制化刻度(主副)绘制
20
用Python自动生成数据分析报告
21
手把手教你用Python操纵Word自动编写离职报告
22
pandas transform 数据转换的 4 个常用技巧!
23
30段极简Python代码:这些小技巧你都Get了么
24
数据处理遇到麻烦不要慌,5个优雅的Numpy函数助你走出困境
25
数据分析最有用的Top 50 Matplotlib图(带有完整的Python代码)(上)
26
数据分析最有用的Top 50 Matplotlib图(带有完整的Python代码)(下)
27
数据分析之Pandas变形操作总结
28
数据分析之Pandas缺失数据处理
29
数据分析之Pandas合并操作总结
30
数据分析之Pandas分组操作总结
31
学习用Pandas处理分类数据!
32
如何用Pandas处理文本数据?
33
Pandas处理时序数据(初学者必会)!
34
Python高阶函数使用总结!
35
机器学习在金融风控的经验总结!
36
你知道怎么用Pandas绘制带交互的可视化图表吗?
37
6个提升效率的pandas小技巧
38
Python数据分析库pandas高级接口dt和str的使用
39
pandas 拼接 concat 5 个常用技巧!
40
pandas分组8个常用技巧!
41
pandas 文本处理大全
42
pandas 筛选数据的 8 个骚操作
43
pandas 分类数据处理大全(附代码)
44
68 个Python内置函数,你用过几个?
45
太秀了!用 pandas 搞定 24 张 Excel 报表
46
用 Python 的 Template 类生成文件报告
47
码如其人,同学你能写一手漂亮的Python函数吗
48
Python处理图片九宫格,炫酷朋友圈
49
Python排序傻傻分不清?一文看透sorted与sort用法
50
python-docx操作word文件(
清单首页python文章详情

用 Python 的 Template 类生成文件报告

介绍

很多时候,我发现自己需要进行生成报告、输出文件或字符串的任务。它们或多或少都会遵循某种模式,通常这些模式是如此相似,以至于我们希望拥有一个可以重用并直接输入数据的模板。幸运的是,Python提供了一个可以帮助我们的类:string.Template

在本文中,您将学习如何利用此类根据当前使用的数据生成输出文件,以及如何以相同的方式操作字符串。因此,本文不仅使用您在日常工作中可能遇到的示例,还为您提供了许多您可能知道的实际工具,并且该工具将此类用于生成报告文件。下面让我们开始吧!

注意:本文基于Python 3.9.0(CPython)。您可以在GitHub(https://github.com/DahlitzFlorian/generate-file-reports-using-pythons-template-class)上找到整篇文章中使用的代码示例。

在看一个示例之前,让我们花一些时间来看看使用string.Template相对于其他解决方案的优势。

1、无需其他依赖项,开箱即用,因此不需要使用pip install命令安装。

2、它是轻量级的,当然诸如Jinja2Mako之类的模板引擎已被广泛使用。但是,在本文介绍的方案中,这些功能是过分地夸大了。

3、关注点分离:可以使用模板文件将其移动到外部位置,而不是直接在代码中嵌入字符串操作和报告生成。如果您要更改报告的结构或设计,则可以交换模板文件,而无需更改代码。

由于这些优点,一些知名的第三方库和工具正在使用它。Wily是一个例子,在2018年底,Wily的发明者和维护者Anthony Shaw希望支持HTML作为wily生成的报告的输出格式。

示例:生成最佳图书的报告

在讨论了使用Python的内置string.Template类背后的动机之后,我们将看一下第一个实际示例。想象一下,您正在一家公司工作,该公司发布有关过去一年出版的最佳书籍的年度报告。2020年是特殊的一年,因为除了您的年度报告之外,您还会发布有史以来最好的书籍清单。

在这一点上,我们不在乎数据来自何处或哪些书籍是该列表的一部分。为了简单起见,我们假设有一个名为data.json的JSON文件,其中包含作者姓名和书名的映射,如下所示。

代码语言:javascript
复制
{
    "Dale Carnegie": "How To Win Friends And Influence People",
    "Daniel Kahneman": "Thinking, Fast and Slow",
    "Leo Tolstoy": "Anna Karenina",
    "William Shakespeare": "Hamlet",
    "Franz Kafka": "The Trial"
}

您现在的任务是以一种可以与他人共享的方式(例如, 大型杂志、公司或博主)。该公司认为使用HTML格式的简单表格就足够了。现在的问题是:如何生成此HTML表格?

当然,您可以手动执行此操作,也可以为每本书创建占位符。但是后面如果能拥有更通用的版本是非常可取的,因为可以扩展列表内容或更改结构设计。

现在我们可以利用Python的string.Template类!我们首先创建实际的模板,如下所示。在这里,我们将文件称为template.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Great Books of All Time</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <h1>Great Books of All Time</h1>
        <table class="table">
            <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">Author</th>
                    <th scope="col">Book Title</th>
                </tr>
            </thead>
            <tbody>
                ${elements}
            </tbody>
        </table>
    </div>
</body>
</html>

该文件本身非常初级。我们使用引导程序进行样式设置,并创建了最终表的基本结构。表头已包含在内,但数据仍然丢失。请注意,在tbody元素中,使用了一个占位符$ {elements}来标记我们稍后将注入书籍列表的位置。

我们把所有都已设置为实现生成所需输出的Python脚本!因此,我们在当前工作目录中创建一个名为report.py的新Python文件。首先,我们导入所需的两个内置模块,并从JSON文件加载数据。

代码语言:javascript
复制
# report.py
import json
import string

with open("data.json") as f:
    data = json.loads(f.read())

现在,data变量是一个字典,其中包含作者的名称(键)和书名(值)作为键值对。接下来,我们生成HTML表,将其放入模板中(还记得占位符吗?)。因此,我们初始化一个空字符串,向其添加新的表行,如下所示。

代码语言:javascript
复制
content = ""
for i, (author, title) in enumerate(data.items()):
    content += "<tr>"
    content += f"<td>{i + 1}</td>"
    content += f"<td>{author}</td>"
    content += f"<td>{title}</td>"
    content += "</tr>"

该代码段显示了我们遍历数据字典中的所有项目,并将书名以及作者的名字放在相应的HTML标签中。我们创建了最终的HTML表。在下一步中,我们需要加载之前创建的模板文件:

代码语言:javascript
复制
with open("template.html") as t:
    template = string.Template(t.read())

注意,string.Template接受一个字符串,而不是一个文件路径。因此,您还可以提供在程序中先前创建的字符串,而无需将其保存到文件中。就我们而言,我们提供了template.html文件的内容。

最后,我们使用模板的replace()方法将占位符元素替换为存储在变量内容中的字符串。该方法返回一个字符串,我们将其存储在变量final_output中。最后但并非最不重要的一点是,我们创建了一个名为report.html的新文件,并将最终输出写入该文件。

代码语言:javascript
复制
final_output = template.substitute(elements=content)
with open("report.html", "w") as output:
    output.write(final_output)

现在已经生成了第一个文件报告!如果在浏览器中打开report.html文件,则可以看到结果。

safe_substitution()方法

现在,您已经构建了第一个string.Template用例,在结束本文之前,我想与您分享一个常见情况及其解决方案:安全替换。它是什么?

让我们举个例子:您有一个字符串,您想在其中输入一个人的名字和姓氏。您可以按照以下步骤进行操作:

代码语言:javascript
复制
# safe_substitution.py
import string

template_string = "Your name is ${firstname} ${lastname}"
t = string.Template(template_string)
result = t.substitute(firstname="Florian", lastname="Dahlitz")
print(result)

但是,如果您错过传递一个或另一个的值会怎样?它引发一个KeyError。为避免这种情况,我们可以利用safe_substitution()方法。在这种情况下,safe意味着Python在任何情况下都尝试返回有效字符串。因此,如果找不到任何值,则不会替换占位符。

让我们按以下方式调整代码:

代码语言:javascript
复制
# safe_substitution.py
import string

template_string = "Your name is ${firstname} ${lastname}"
t = string.Template(template_string)
result = t.safe_substitute(firstname="Florian")
print(result)  # Your name is Florian ${lastname}

在某些情况下,这可能是一个更优雅的解决方案,甚至是必须的行为。但是这可能在其他地方引起意外的副作用。

本文概要

在阅读本文时,您不仅学习了Python字符串的基本知识。Template类以及使用它的原因,而且还实现了第一个文件报告脚本!此外,您已经了解了safe_substitution()方法以及在哪种情况下使用它可能会有所帮助。

代码语言:javascript
复制
下一篇
举报
领券