个性化阅读
专注于IT技术分析

使用Jinja2的Jupyter Notebook的自定义模板

本文概述

在数据科学中, 你通常需要创建工作报告以显示给决策者或其他非技术人员。将Jupyter Notebook转换成稳定的PDF或HTML文档, 对于没有安装Python或Jupyter的同事来说更容易。 Python使用名为nbconvert的库和名为Jinja2的模板语言来转换文档。模板定义如何将文档显示在网页或其他输出格式上。了解如何自定义模板有助于制作出精美的笔记本报告。

Jupyter Notebook是在浏览器中运行Python代码的一种方式。如果你想了解有关Python的更多信息, 请务必查看我们的免费的Python数据科学入门课程。

在本教程中, 你将涵盖以下主题:

  • 模板和Jinja2模板设计器。
  • 渲染模板和继承。
  • 如何使用nbconvert导出笔记本。
  • 用于扩展Jupyter默认模板以进行HTML导出的语法和结构。
  • 导出为LaTeX和PDF格式的区别。

什么是模板?

在Python Wiki中:”模板化, 尤其是Web模板化, 是一种以不同形式表示数据的方式……模板化解决方案经常涉及文档(模板)和数据。模板通常看起来像最终输出, 带有占位符, 而不是实际数据”

通过使用文件->下载为(可以在Jupyter实验室中看到导出为笔记本), 可以轻松地导出Jupyter Notebook。该选项使用Jupyter主环境中保存的默认模板。 Jinja2是Python强大的模板语言, 用于定义阻止和排版。模板具有由标签定义的部分, 这些部分告诉模板如何呈现输入数据。呈现模板时, 数据将替换变量或表达式。

模板不同部分的分隔符为:

  • {%…%}的报表
  • {{…}}用于表达式打印到模板输出
  • {#…#}表示注释未包含在模板输出中

看一下这个简短的Jinja模板示例(由Jinja2文档提供):

<!DOCTYPE html>

<html lang="en">

<head>

    {% block head %}
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}{% endblock %} - My Webpage </title>
    {% endblock %}
</head>

<body>

    <div id="content">{% block content %}{% endblock %}</div>
    <div id="footer">
        {% block footer %}
        &copy; Copyright 2008 by <a href="http://domain.invalid/">you </a>.
        {% endblock %}
    </div>
</body>

</html>

你可以在上面看到, 大多数模板类似于普通的HTML文档。 Jinja需要一些额外的行来将代码解释为模板。 {%block head%}定义HTML文档的head部分, 以及此模板将如何扩展其格式。 {%块标题%}部分描述了输入标题的显示位置。 {%endblock%}会出现在多个位置, 因为这会结束任何相应的模板块。

现在, 你准备好学习如何使用Jinja创建自己的自定义模板!

神社简介

Jinja是一个模板引擎, 可让你定义文档的显示方式。具体来说, 对于本教程, 你将重点介绍如何在Jinja模板的帮助下导出Jupyter Notebook。

首先, 从Jinja2导入模板:

from jinja2 import Template

了解带有模板的基本渲染

在Jinja模板中渲染数据非常简单。使用方括号和变量名, 可以在模板中显示数据:

myTemplate = Template("My template is {{ something }}!")
myTemplate.render(something="awesome")
'My template is awesome!'

调用.render(input)可以使你的笔记本中显示模板, 而输入内容将替换模板中的通用{{something}}。这是Jinja中的表达式用法示例。

你可以通过定义Jinja会解释的Python语句来更动态地使用模板。

myFancyTemplate = Template("Let's count to 10: {% for i in range(11) %}{{i}} " "{% endfor %}")
myFancyTemplate.render()
"Let's count to 10: 0 1 2 3 4 5 6 7 8 9 10 "

注意, 你定义了一个for循环, 并且模板以0到10之间的数字呈现数字。 {%expression%}的语句语法为创建自定义模板提供了很大的灵活性。

模板继承

为了制作扩展默认Jupyter导出的模板, 你可以使用模板继承。继承是编程中的概念, 你可以在子对象中实现一些可以利用父级定义的功能的对象。一个简单的示例是, 如果你有一个可以吠叫, 吃饭和散步的Dog对象, 则可以使用继承来创建Dalmatian对象, 该对象可以继承所有这些属性并添加其他属性, 例如有斑点。在本教程中, 你将看到继承对于模板化非常有用, 因为通常只需要进行很小的更改即可自定义输出。像其他继承语言一样, Jinja使用extend和super之类的关键字来访问父级定义。

看一看上面的示例父模板, 名为base.html:

<!DOCTYPE html>
<html lang="en">

<head>
    {% block head %}
    <link rel="stylesheet" href="style.css" />
    <title>{% block title %}{% endblock %} - My Webpage </title>
    {% endblock %}
</head>

<body>
    <div id="content">{% block content %}{% endblock %}</div>
    <div id="footer">
        {% block footer %}
        &copy; Copyright 2008 by <a href="http://domain.invalid/">you </a>.
        {% endblock %}
    </div>
</body>

</html>

子模板可能看起来像这样(由Jinja2文档提供):

{% extends "base.html" %}

{% block title %}Index{% endblock %}

{% block head %}
    {{ super() }}
    <style type="text/css">
        .important { color: #336699; }
    </style>
{% endblock %}

{% block content %}
    <h1>Index</h1>
    <p class="important">
      Welcome to my awesome homepage.
    </p>
{% endblock %}

请注意, 子模板如何以{%扩展” base.html”%}开头。该声明告诉Jinja模板引擎如何处理此文档(作为具有base.html继承的HTML)。使用此子模板可以为首页指定不同的属性(例如特定的CSS颜色)。同样, 你可以在head块中看到子模板通过调用super()继承了父模板的样式。

使用nbconvert导出Jupyter Notebook

现在, 你了解了模板的基本语法和继承, 你可以学习如何使用nbconvert导出Jupter Notebook并定义模板以自定义输出。

首先导入nbconvert:

import nbconvert

nbconvert可以创建多种格式的输出。本教程将重点介绍HTML和LaTeX / PDF输出。要在笔记本中查看输出, 请在调用nbconvert时使用IPython显示功能和–stdout。

example = !jupyter nbconvert --to html 'Example.ipynb' --stdout
from IPython.display import HTML, display
display(HTML('\n'.join(example)))

[NbConvertApp]将笔记本Example.ipynb转换为html

使用Jinja2的Jupyter Notebook的自定义模板1

笔记本的此代码段看起来与原始.ipynb文件非常相似。输出显示为独立的文档, 带有标题和文本, 通常在笔记本中显示。代码单元块显示为灰色框(称为”笔记本样式”)。你可以看到的主要区别是Jupyter默认的HTML模板不像活动的Notebook那样显示” Out:”提示。

使用nbconvert和自定义子模板导出Jupyter Notebook

通常, 你需要扩展Jupyter Notebook的默认导出模板, 并对输出进行较小的设计更改。

例如, 看下面这个简单的模板, 该模板从输出中删除Markdown单元(称为rmMkdwn.tpl):

{% extends 'basic.tpl'%}

{% block markdowncell -%}
{% endblock markdowncell %}

通过–template =选项将模板应用于nbconvert:

example = !jupyter nbconvert --to html 'Example.ipynb' --template='rmMkdwn.tpl' --stdout
display(HTML('\n'.join(example)))

[NbConvertApp]将笔记本Example.ipynb转换为html

使用Jinja2的Jupyter Notebook的自定义模板2

即使是一个非常简单的模板, 例如rmMkdwn.tpl, 也可以极大地帮助你自定义输出。

看一下这个更复杂的模板, 该模板将单元格用红色框起来(称为boxRed.tpl):

{% extends 'full.tpl'%}

{% block any_cell %}
    <div style="border:thin solid red">
        {{ super() }}
    </div>
{% endblock any_cell %}
example = !jupyter nbconvert --to html 'Example.ipynb' --template='boxRed.tpl' --stdout
display(HTML('\n'.join(example)))

[NbConvertApp]将笔记本Example.ipynb转换为html

使用Jinja2的Jupyter Notebook的自定义模板3

在上方, 你可以看到唯一的样式更改是每个单元格周围的红色框。 super()用于确保每个单元格都保持其父模板full.tpl中的样式。

导出到LaTeX和PDF模板的差异

由于{}和%在LaTeX中是特殊字符, 因此必须使用(())和*。同样, 默认的LaTeX模板是base.tplx, article.tplx和report.tplx, 它们对应于LaTeX文档类。

看一下使用LaTeX子模板删除Markdown单元格:

((* extends 'article.tplx' *))

((* block markdowncell -*))
((* endblock markdowncell *))

nbconvert可以生成LaTeX或PDF输出-从LaTeX模板编译PDF输出。为了便于阅读, 请查看使用rmMkdwn.tplx导出为PDF时发生的情况。

!jupyter nbconvert --to pdf 'Example.ipynb' --template='rmMkdwn.tplx'
from IPython.display import IFrame
IFrame('Example.pdf', width=800, height=500)
[NbConvertApp] Converting notebook Example.ipynb to pdf
[NbConvertApp] Support files will be in Example_files/
[NbConvertApp] Making directory Example_files
[NbConvertApp] Writing 16047 bytes to notebook.tex
[NbConvertApp] Building PDF
[NbConvertApp] Running xelatex 3 times: ['xelatex', 'notebook.tex']
[NbConvertApp] Running bibtex 1 time: ['bibtex', 'notebook']
[NbConvertApp] WARNING | bibtex had problems, most likely because there were no citations
[NbConvertApp] PDF successfully created
[NbConvertApp] Writing 16102 bytes to Example.pdf
使用Jinja2的Jupyter Notebook的自定义模板4

注意, 此输出结果与HTML版本截然不同。 LaTeX将第一个Markdown单元提供给文章标题, 因此它仍显示在输出中。模板确实正确删除了字幕(因此将Markdown单元视为真正的Markdown)。文章文档类将以今天的日期进行更新-这不是原始笔记本中的日期。字体和间距与HTML版本不同。最后, 默认情况下, 输出使用经典的IPython显示, 而不是”笔记本样式”显示。

如果你选择扩展Jupyter中的LaTeX文档类, 请确保你了解它将使用的格式。

总结

关于模板, Jinja2和nbconvert有一些重要的事情要记住。

模板定义如何将文档显示在网页或其他输出格式上。 Jupyter Notebook实现了Jinja模板以显示不同的导出格式。模板具有继承规则, 使你可以为格式相似的页面定义父模板和子模板。

Jinja模板具有语句, 表达式和(可选)注释。由{%statement%}定义的语句定义模板结构。由{{expression}}定义的表达式会用你的数据填充模板。由{#comment#}定义的注释不会显示在输出中-它们仅在模板内部。

nbconvert是一个Python库, 可让你将Jupyter Notebook转换为其他格式, 例如HTML, LaTeX和PDF。 nbconvert使用Jinja模板定义如何以这些格式显示Jupyter Notebook。你可以使用继承定义自定义模板或扩展默认的Jupyter模板。

现在, 你可以开始制作自己的模板并导出漂亮的Jupyter Notebook文档了!

参考文献:

Jinja2文档

Python模板文档

nbconvert文档

赞(0)
未经允许不得转载:srcmini » 使用Jinja2的Jupyter Notebook的自定义模板

评论 抢沙发

评论前必须登录!