Skip to content

magic_commands

魔术命令(Magic commands)是 IPython 内核(kernel)最强大、最便捷的特性之一,显著增强了交互式 Python 体验。它们提供了超越标准 Python 语法(syntax)的快捷方式和扩展功能,常用于控制环境、与操作系统(operating system)交互、代码计时等。

可以将它们视为 IPython 拦截并直接处理的特殊命令,前缀是 % 或 %%。

魔术命令分为两种类型:

  • 行魔术命令(Line magics):前缀是单个 %,作用于输入的单行内容。
  • 单元格魔术命令(Cell magics):前缀是 %%,作用于该魔术命令下方整个代码单元格的内容。

行魔术命令的功能类似于命令行调用。魔术命令后面的其余部分构成其参数(arguments),通常无需括号或引号传递(不过参数包含空格时需要引号)。某些行魔术命令可以返回值并赋给变量。

单元格魔术命令应用于它所在的单元格的整个多行内容。魔术命令必须是单元格中的第一项。它们可以用多种方式处理单元格内容——甚至无需是 Python 代码(例如,%%bash, %%html)。

你可以使用以下命令列出所有可用的魔术命令:

%lsmagic

要获取特定魔术命令的帮助,可以使用 ?:

%timeit?

可以通以下命令获取魔术命令的快速参考卡:

%quickref

在当前 IPython 命名空间(namespace)内运行一个外部 Python 脚本(script)文件。

# my_script.py 的内容:
# message = "Hello from script!"
# print(message)
%run my_script.py
# 输出:Hello from script!
print(message) # 脚本中定义的变量现在可用
# 输出:Hello from script!

将代码从外部脚本、URL 或历史记录条目加载到当前单元格中,以便编辑和执行。

# 单元格 1:
%load my_script.py
# 单元格 1 执行后变为:
# %load my_script.py
message = "Hello from script!"
print(message)

测量单个 Python 语句(statement)的执行时间(execution time)(行魔术命令)。

%time my_list = [x**2 for x in range(10000)]
# 输出:CPU 时间:user X 毫秒, sys: Y 毫秒, total: Z 毫秒
# 实际时间:W 毫秒

通过多次运行来更准确地测量语句的执行时间。作为行魔术命令和单元格魔术命令均可用。

# 行魔术命令
%timeit my_list = [x**2 for x in range(1000)]
# 输出:每次循环 X 微秒 +- Y 纳秒 (Z 次运行的均值 +- 标准差,每次运行 W 个循环)
# 单元格魔术命令
%%timeit
my_list = []
for x in range(1000):
my_list.append(x**2)
# 输出:整个单元格类似的计时信息

显示会话(session)期间输入的先前命令。

%history -n 1-3 # 显示输入行 1 到 3

%who 列出当前命名空间中的变量。%whos 提供更多详细信息(类型、值/信息)。

a = 10
b = 'hello'
%who
# 输出:a b
%whos
# 输出:
# 变量
# 类型
# 数据/信息
# -----------------------------
# a int 10
# b str hello

%pwd 打印当前工作目录。%cd 更改目录。

%pwd
# 输出:/home/user/myproject
%cd ../anotherproject
# 输出:/home/user/anotherproject
%pwd
# 输出:/home/user/anotherproject

配置 Matplotlib 图表如何显示。常见的后端(backends)有:

  • %matplotlib inline: 图表直接显示在生成它们的代码单元格下方(静态图像)。
  • %matplotlib widget: 图表显示在单元格下方,带有交互式控件(requires ipympl installed)。
  • %matplotlib notebook: 类似于 widget,提供交互性(interactivity)(较旧,有时不如 widget 稳定)。
  • %matplotlib qt / tk / 等:使用指定的 GUI 工具包(toolkits)在单独的窗口中显示图表(在 notebook 中较少使用)。
%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 2 * np.pi, 100)
y = np.sin(x)
plt.plot(x, y)
plt.title("Sine Wave")
plt.show()
# 图表显示在此单元格下方

当开发自己的 Python 模块(modules)时非常有用。它会在执行代码前自动重载(reload)模块,因此你在外部 .py 文件中所做的更改无需重启内核(kernel)即可反映。

%load_ext autoreload
%autoreload 2
import my_module # 导入你的自定义模块
# 现在,如果你编辑 my_module.py 并保存它,
# 下次调用 my_module 中的函数时,
# 更改将被自动加载,无需重启
# 或手动重载。

列出、获取或设置当前会话的环境变量(environment variables)。

%env # 列出所有
%env PATH # 获取 PATH 的值
%env MY_VAR=my_value # 设置 MY_VAR(仅对当前会话生效)

一种便捷的方式,可以直接在 notebook 单元格中安装软件包(packages),使用与当前内核(kernel)关联的相应软件包管理器(package manager)。

%pip install requests
# 如果使用 conda 环境:
# %conda install scikit-learn

在发生异常(exception)后激活交互式调试器(debugger)(pdb 或 ipdb)。在引发错误的单元格之后立即调用它。

# 单元格 1:
def my_func(x):
return 1 / x
my_func(0)
# 单元格 2(在单元格 1 失败后立即运行):
%debug

其他语言/格式的单元格魔术命令

Section titled “其他语言/格式的单元格魔术命令”

IPython 允许直接在单元格内执行其他语言的代码或渲染不同的格式(formats):

%%bash
ls -l
echo "Hello from Bash!"
%%html
<h1>This is HTML</h1>
<p>Rendered directly in the output.</p>
%%javascript
console.log('Hello from JavaScript!');
alert('This runs in the browser console.');
%%writefile my_new_script.py
# 此单元格的内容将保存到 my_new_script.py
print("This content is written to a file.")
def new_function():
return 'Success!'

这个魔术命令将 NumPy 和 Matplotlib 中的许多函数直接导入到全局命名空间(global namespace)中(例如,你可以直接调用 plot() 而不是 plt.plot())。虽然对于非常快速的交互式会话很方便,但对于任何严肃的工作或脚本,这是强烈不推荐的,原因如下:

  • 它污染了命名空间,使得函数的来源不明确。
  • 它可能导致命名冲突(naming conflicts)。
  • 它使代码更难阅读和理解。
  • 它偏离了标准的 Python 实践。

最佳实践是始终使用显式导入(explicit imports):

import numpy as np
import matplotlib.pyplot as plt

你可以使用 IPython.core.magic 中的装饰器(decorators)定义自己的魔术函数。

from IPython.core.magic import register_line_magic
@register_line_magic
def greet(line):
"""A simple line magic that greets someone."""
name = line or 'World'
print(f"Hello, {name}!")
# 现在你可以使用它了:
%greet
# 输出:Hello, World!
%greet Alice
# 输出:Hello, Alice!

魔术命令是 IPython 和 Jupyter 提供的增强交互体验(interactive experience)的基石,使许多常见任务更简单高效。