使用 Python

概述

Quarto 支持在 Markdown 中嵌入可执行的 Python 代码块。这使您能够创建完全可重复的文档和报告——生成输出所需的 Python 代码本身就是文档的一部分,并且在渲染文档时会自动重新运行。

如果您已经安装了 Python 和 jupyter 包,那么您已经具备了渲染包含嵌入式 Python 代码的文档所需的一切(如果没有,我们将在下面的 安装 部分介绍)。接下来,我们将介绍创建和渲染包含 Python 代码块的文档的基础知识。

代码块

使用花括号包围语言名称的代码块(例如 ```{python})是可执行的,并在渲染时由 Quarto 运行。以下是一个简单的示例:

---
title: "matplotlib 演示"
format:
  html:
    code-fold: true
jupyter: python3
---

要查看极坐标轴上的线图演示,请参见 @fig-polar。

```{python}
#| label: fig-polar
#| fig-cap: "极坐标轴上的线图"

import numpy as np
import matplotlib.pyplot as plt

r = np.arange(0, 2, 0.01)
theta = 2 * np.pi * r
fig, ax = plt.subplots(
  subplot_kw = {'projection': 'polar'} 
)
ax.plot(theta, r)
ax.set_rticks([0.5, 1, 1.5, 2])
ax.grid(True)
plt.show()
```

您会注意到代码块顶部有一些特殊的注释。这些是单元格级别的选项,使图形可以 交叉引用

此文档将生成以下渲染输出:

示例输出,标题为:matplotlib 演示,正文为:要查看极坐标轴上的线图演示,请参见图 1。正文下方是一个可切换的字段以显示代码,以及图 1 的图像,标题为:图 1:极坐标轴上的线图。

您可以从可执行代码块生成多种输出类型,包括图表、数据框的表格输出以及纯文本输出(例如打印统计摘要的结果)。

有许多选项可以控制代码执行和输出的行为,您可以在 执行选项 文章中了解更多信息。

除了中断 Markdown 流程的代码块外,您还可以包含内联代码。在 内联代码 文章中了解更多信息。

渲染

Quarto 会自动运行包含可执行代码块的任何 Markdown 文档中的计算。例如,上面的示例可以通过以下方式渲染为各种格式:

终端
quarto render document.qmd # 所有格式
quarto render document.qmd --to pdf
quarto render document.qmd --to docx

render 命令将渲染文档 YAML 中列出的所有格式。如果没有指定格式,则将渲染为 HTML。您还可以提供 --to 参数以针对特定格式。

Quarto 还可以渲染任何 Jupyter 笔记本(.ipynb):

终端
quarto render document.ipynb

请注意,目标文件(在本例中为 document.qmd)应始终是命令行参数中的第一个参数。

请注意,在渲染 .ipynb 时,Quarto 默认不会执行笔记本中的单元格(假设您在编辑笔记本时已经执行了它们)。如果您想执行这些单元格,可以传递 --execute 标志给 render:

终端
quarto render notebook.ipynb --execute

安装

如果您已经在环境中安装了 Python 3 和 Jupyter,那么您应该已经具备了使用 Python 内核渲染 Jupyter notebook 所需的一切。

如果你系统上还没有 Python 3,我们建议你使用来自 https://www.python.org/downloads/ 的标准安装程序安装一个版本。

如果你在一个全新的 Python 3 环境中,安装 jupyter 包将提供运行 Quarto 的 Jupyter 内核所需的一切:

包管理器 命令
Pip
(Mac/Linux)
Terminal
python3 -m pip install jupyter
Pip
(Windows)
Terminal
py -m pip install jupyter
Conda
Terminal
conda install jupyter

你可以通过以下命令验证 Quarto 是否正确配置了 Jupyter:

Terminal
quarto check jupyter

Quarto 将在 Windows 上使用 Python 启动器 或在 MacOS 和 Linux 上使用系统 PATH 选择一个 Python 版本。你可以通过设置 QUARTO_PYTHON 环境变量来覆盖 Quarto 使用的 Python 版本。

工作流程

您可以使用任何文本或笔记本编辑器编写包含Python代码的Quarto文档。无论您使用哪种编辑工具,始终首先运行quarto preview来设置文档更改的实时预览。实时预览适用于HTML和PDF输出。例如:

终端
# 以HTML预览
quarto preview document.qmd

# 以PDF预览
quarto preview document.qmd --to pdf

# 预览Jupyter笔记本
quarto preview document.ipynb

请注意,当渲染一个 .ipynb 文件时,Quarto 默认不会 执行笔记本中的单元格(假设你在编辑笔记本时已经执行过这些单元格)。如果你想执行这些单元格,可以在渲染时传递 --execute 标志:

Terminal
quarto render notebook.ipynb --execute

你也可以在笔记本的 YAML 前文中指定这种行为:

---
title: "My Notebook"
execute: 
  enabled: true
---

嵌入笔记本

除了在Quarto文档中包含可执行的Python代码块外,您还可以嵌入外部Jupyter笔记本(.ipynb)中的单元格。有关更多详细信息,请参阅嵌入Jupyter笔记本单元格

VS Code

VS Code的Quarto扩展为在VS Code中处理.qmd文件提供了多种工具。该扩展直接与Python 扩展集成,提供以下Python特定功能:

  1. 代码补全
  2. 单元格执行
  3. 上下文帮助

VS Code 编辑器的屏幕截图,分为三个垂直部分。最左边包括文件资源管理器和 Quarto 帮助。第二个窗格是包含 Python 代码的 Quarto 文件的源代码。第三个窗格是交互式的,正在运行 Python 并显示代码单元格的输出。

您可以通过在扩展面板中搜索’quarto’或从扩展市场安装VS Code扩展。

您还可以使用VS Code笔记本编辑器创建Python笔记本,这些笔记本将使用Quarto进行渲染。下一节将讨论在Jupyter Lab上下文中使用笔记本与Quarto,但同样的概念也适用于VS Code。

Jupyter Lab

我们可以使用quarto convert命令将上面示例中使用的简单document.qmd转换为Jupyter笔记本。例如:

终端
quarto convert document.qmd

如果我们在Jupyter Lab中打开此笔记本并执行单元格,我们会看到以下内容:

一个标题为 Quarto Basics 的 Jupyter notebook,包含一些文本、一个代码单元格以及代码单元格的结果,这是一个极坐标轴上的线图。

请注意,这里有三种不同类型的单元格:

  1. 顶部的YAML文档选项位于Raw单元格中。
  2. 标题和解释位于Markdown单元格中。
  3. Python代码及其输出位于Code单元格中。

在Jupyter笔记本中工作时,您可以使用quarto preview来提供渲染文档的实时预览:

终端
quarto preview document.ipynb

每次在Jupyter Lab中保存笔记本时,预览都会更新。

缓存

Jupyter Cache 允许您缓存笔记本中所有单元格的输出。如果笔记本中的任何单元格发生变化,则所有单元格都将重新执行。

要使用 Jupyter Cache,您首先需要安装 jupyter-cache 包:

平台 命令
Mac/Linux
Terminal
python3 -m pip install jupyter-cache
Windows
Terminal
py -m pip install jupyter-cache

要为文档启用缓存,请添加 cache 选项。例如:

---
title: "我的文档"
format: html
execute: 
  cache: true
---

您还可以在项目级别指定缓存。例如,在项目文件中:

project:
  type: website
  
format:
  html:
    theme: united
    
execute:
  cache: true

请注意,文档中不在代码单元格内的更改(例如 Markdown 叙述)不会使文档缓存失效。这使得缓存在您仅处理文档的散文部分时成为一个非常方便的选项。

Jupyter Cache 包含一个 jcache 命令行工具,您可以使用它来分析和管理笔记本缓存。有关更多详细信息,请参阅 Jupyter Cache 文档。

渲染

你可以使用 quarto render 命令行选项来控制缓存行为,而无需更改文档代码。使用这些选项可以强制所有代码块使用缓存,禁用所有代码块的缓存(即使选项中指定了缓存),或者强制刷新缓存,即使它未失效:

终端
# 使用缓存(即使未在选项中启用)
quarto render example.qmd --cache 

# 不使用缓存(即使选项中启用了缓存)
quarto render example.qmd --no-cache 

# 使用缓存并强制刷新
quarto render example.qmd --cache-refresh 

替代方案

如果你使用缓存来缓解长时间渲染的问题,你应该考虑一些与缓存并行的替代方案。

禁用执行

如果你只处理散文/Markdown,你可能希望完全禁用执行。通过指定 enabled: false 执行选项来实现这一点。例如:

---
title: "我的文档"
format: html
execute: 
  enabled: false
---

请注意,如果你使用 Jupyter .ipynb 笔记本(而不是纯文本 .qmd 文件)进行创作,那么这已经是默认行为:当你调用 quarto render 时不会发生执行(相反,执行会在你使用笔记本时发生)。

冻结执行

如果你在一个项目中工作,并且你主要关心的是同时渲染许多文档的累积影响,请考虑使用 freeze 选项。

你可以使用 freeze 选项来表示在全局项目渲染期间,计算文档不应重新渲染,或者仅在源文件更改时重新渲染:

execute:
  freeze: true  # 在项目渲染期间永不重新渲染
execute:
  freeze: auto  # 仅在源文件更改时重新渲染

请注意,freeze 控制的是在全局项目渲染期间是否执行。如果你对单个文档或项目子目录进行增量渲染,那么代码总是会被执行。例如:

Terminal
# 渲染单个文档(总是执行代码)
quarto render document.qmd

# 渲染项目子目录(总是执行代码)
quarto render articles

在关于 管理项目执行 的文章中了解更多关于使用 freeze 的信息。

内核选择

Quarto 使用的 Jupyter 内核通过 jupyter 元数据选项确定。例如,要使用 Xeus Python 内核,请执行以下操作:

---
title: "我的文档"
jupyter: xpython
---

请注意,您还可以提供完整的 kernelspec,例如:

---
title: "我的文档"
jupyter: 
  kernelspec:
    name: "xpython"
    language: "python"
    display_name: "Python 3.7 (XPython)"
---

如果没有指定 Jupyter 内核,那么内核将通过查找文件中找到的第一个可执行代码块支持的语言来确定(例如 ```{python})。

Conda 中的内核

如果您使用的是包含在外部 conda 环境中的内核,您需要采取额外步骤以确保 Quarto 能够识别它。请按照以下说明使 conda 管理的内核可用:

https://github.com/Anaconda-Platform/nb_conda_kernels#use-with-nbconvert-voila-papermill

请注意,如果您只是将 conda 与 Quarto 一起使用,则不需要此步骤。它适用于使用默认 Python 内核以外的内核,这些内核恰好安装在与您使用的环境分开的 conda 环境中。

内核守护进程

为了减少Jupyter内核的启动时间,Quarto为每个文档保持一个运行中的Jupyter内核的守护进程。这使得后续的渲染可以立即进行,而无需等待内核启动。

守护进程的目的是在交互会话期间使渲染更加响应迅速。因此,当文档在没有活动tty的情况下渲染或作为批量渲染的一部分时(例如在Quarto项目中),不会创建守护进程。

请注意,Quarto默认情况下不会在Windows上使用守护进程(因为某些Windows系统不允许守护进程所需的套接字连接)。

您可以使用daemon执行选项自定义此行为。将其设置为false以防止使用守护进程,或将其设置为一个值(以秒为单位)以确定守护进程超时的时间段(默认值为300秒)。例如:

execute:
  daemon: false
execute:
  daemon: 60

请注意,如果您想在Windows上使用守护进程,您需要显式启用它:

execute:
  daemon: true

命令行

您还可以使用以下命令行选项控制Jupyter守护进程的使用:

终端
# 使用默认超时(300秒)的守护进程
quarto render document.qmd --execute-daemon

# 使用显式超时的守护进程
quarto render document.qmd --execute-daemon 60

# 防止使用守护进程
quarto render document.qmd --no-execute-daemon

您还可以使用--execute-daemon-restart命令行标志强制重新启动现有的守护进程:

终端
quarto render document.qmd --execute-daemon-restart 

如果您怀疑重用笔记本会话会导致错误,这可能会有用。

最后,您可以使用--execute-debug标志打印有关守护进程使用情况的扩展调试信息(启动、关闭、连接等):

终端
quarto render document.qmd --execute-debug