很多時候,我發現自己需要進行產生報表、輸出檔案或字串的任務。它們或多或少都會遵循某種模式,通常這些模式是如此相似,以至於我們希望擁有一個可以重複使用並直接輸入資料的範本。幸運的是,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、它是輕量級的,當然諸如Jinja2和Mako之類的模板引擎已被廣泛使用。但是,在本文介紹的方案中,這些功能是過度誇大了。
3、關注點分離:可以使用範本檔案將其移動到外部位置,而不是直接在程式碼中嵌入字串操作和報告產生。如果您要變更報表的結構或設計,則可以交換範本文件,而無需變更程式碼。
由於這些優點,一些知名的第三方函式庫和工具正在使用它。 Wily是一個例子,在2018年底,Wily的發明者和維護者Anthony Shaw希望支援HTML作為wily產生的報告的輸出格式。
範例:產生最佳書籍的報告
在討論了使用Python的內建string.Template類別背後的動機之後,我們將看一下第一個實際範例。想像一下,您正在一家公司工作,該公司發布有關過去一年出版的最佳書籍的年度報告。 2020年是特別的一年,因為除了您的年度報告之外,您還會發布有史以來最好的書籍清單。
在這一點上,我們不在乎資料來自何處或哪些書籍是該清單的一部分。為了簡單起見,我們假設有一個名為data.json的JSON文件,其中包含作者姓名和書名的映射,如下所示。
{ "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。
<!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> <h1>Great Books of All Time</h1> <table > <thead> <tr> <th scope="col">#</th> <th scope="col">Author</th> <th scope="col">Book Title</th> </tr> </thead> <tbody> ${elements} </tbody> </table> </body> </html>
該檔案本身非常初級。我們使用引導程式進行樣式設置,並創建了最終表的基本結構。表頭已包含在內,但資料仍遺失。請注意,在tbody元素中,使用了一個佔位符$ {elements}來標記我們稍後將注入書籍清單的位置。
我們把所有都設定為實作產生所需輸出的Python腳本!因此,我們在目前工作目錄中建立一個名為report.py的新Python檔。首先,我們導入所需的兩個內建模組,並從JSON檔案載入資料。
# report.py import json import string with open("data.json") as f: data = json.loads(f.read())
現在,data變數是一個字典,其中包含作者的名稱(鍵)和書名(值)作為鍵值對。接下來,我們產生HTML表,將其放入模板中(還記得佔位符嗎?)。因此,我們初始化一個空字串,向其添加新的表行,如下所示。
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表。在下一步中,我們需要載入先前建立的範本檔案:
with open("template.html") as t: template = string.Template(t.read())
注意,string.Template接受一個字串,而不是一個檔案路徑。因此,您也可以提供程式中先前建立的字串,而無需將其儲存到檔案中。就我們而言,我們提供了template.html檔案的內容。
最後,我們使用模板的replace()方法將佔位符元素替換為儲存在變數內容中的字串。該方法傳回一個字串,我們將其儲存在變數final_output中。最後但並非最不重要的一點是,我們創建了一個名為report.html的新文件,並將最終輸出寫入該文件。
final_output = template.substitute(elements=content) with open("report.html", "w") as output: output.write(final_output)
现在已经生成了第一个文件报告!如果在浏览器中打开report.html文件,则可以看到结果。
safe_substitution()方法
现在,您已经构建了第一个string.Template用例,在结束本文之前,我想与您分享一个常见情况及其解决方案:安全替换。它是什么?
让我们举个例子:您有一个字符串,您想在其中输入一个人的名字和姓氏。您可以按照以下步骤进行操作:
# 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在任何情况下都尝试返回有效字符串。因此,如果找不到任何值,则不会替换占位符。
让我们按以下方式调整代码:
# 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()方法以及在哪种情况下使用它可能会有所帮助。
以上是用 Python 的 Template 類別產生檔案報告的詳細內容。更多資訊請關注PHP中文網其他相關文章!