jupyter notebook 默认只显示最后一个表达式是因为 ipython 内核的 ast_node_interactivity 默认设为 "last",仅渲染单元格末尾可显示对象;设为 "all" 或用 display() 可实现多输出。

为什么默认只显示最后一个表达式?
Jupyter Notebook 的行为由 IPython 内核的 ast_node_interactivity 控制,默认值是 "last"——它只把单元格里最后一行**可显示对象**(如 df、plt.gcf())交给 display hook 渲染,其余语句的返回值被丢弃。这不是 bug,而是设计选择:避免意外输出大量中间结果干扰阅读。
设置 ast_node_interactivity = "all" 是最直接解法
执行以下两行代码即可让当前 notebook 所有后续单元格自动显示每行独立表达式的输出:
from IPython.core.interactiveshell import InteractiveShell InteractiveShell.ast_node_interactivity = "all"
常见使用场景包括:
- 快速对比
df.head()和df.tail() - 同时查看
df.shape、df.dtypes、df.isna().sum() - 在探索阶段连续调用多个
print()+ 表格 + 图表(注意:print()本身不受此设置影响,始终可见)
⚠️ 容易踩的坑:
- 该设置仅对当前 kernel 生效,重启 kernel 后失效;若需永久生效,需写入
~/.ipython/profile_default/ipython_config.py - 开启后,所有行末尾带返回值的语句都会输出,比如
df.sort_values("x")会重复渲染整个表格,可能拖慢响应 —— 此时可在不需要显示的行末加;抑制(尤其适用于 matplotlib 调用)
用 display() 显式控制多输出更灵活
当只需要某几个变量输出、或想混合文本/表格/图像时,display() 比全局设置更精准:
from IPython.display import display
display("Summary stats:")
display(df.describe())
display("Top 3 rows:")
display(df.head(3))
优势在于:
- 不依赖内核配置,脚本可移植性强
- 支持传入多个参数:
display(a, b, c)会依次渲染 - 能混排不同 mime 类型对象(如
display(df, plt.gcf(), "done"))
⚠️ 注意:display() 不会抑制前序语句的默认输出,所以和 ast_node_interactivity="all" 叠加使用时可能重复 —— 建议二者选其一,别混用。
matplotlib 图表+文本共存时的典型陷阱
写 plt.plot(...); plt.show() 本意是只出图,但若前面还有 df.head() 且启用了 "all" 模式,就会先刷表格再刷图,还可能附带 <figure size ...></figure> 文字。
解决办法很明确:
- 图表行末加
;:如plt.hist(df.x);—— 这会抑制 matplotlib 对象的文本 repr 输出 - 或统一用
display(plt.gcf())替代plt.show(),确保只输出图像本身 - 避免在同一个单元格里既用
print()又依赖自动显示,因为print()总是立即输出,顺序不可控
真正麻烦的不是怎么让多个东西出来,而是控制它们出来的时机、格式和干净程度——尤其是当表格列宽撑破单元格、或图像分辨率太低时,display() 配合 HTML 或 CSS 才是下一步要碰的硬茬。











