Skip to content

IPython - 魔术命令

魔术命令是 IPython 的一个突出特点,提供了方便的快捷方式,并能控制 IPython 环境和底层系统。它们通常能简化使用标准 Python 语法会更繁琐的任务,这使得它们在交互式数据分析和工作流程管理中特别有用。

这些命令以 ’%’ 或 ’%%’ 作为前缀,在你的 IPython 会话中(包括 Jupyter Notebooks 和 JupyterLab)就像迷你命令行工具一样。

魔术命令主要有两种类型:

  • 行魔术(Line Magics):以单个 ’%’ 为前缀,作用于单行输入。
  • 单元格魔术(Cell Magics):以 ’%%’ 为前缀,作用于魔术命令下方的整个代码单元格。

行魔术的功能类似于 shell 命令。它们以 ’%’ 字符开头,行的其余部分包含其参数,通常没有括号或引号。行魔术的输出通常可以分配给 Python 变量。

单元格魔术以 ’%%’ 开头,作用于调用它们的单元格中的整个代码块。它们将整个单元格内容作为一个字符串处理,从而允许在不同的上下文(例如,运行 bash 脚本、写入文件)中进行强大的转换或执行。

你可以使用 %lsmagic 列出所有可用的魔术命令。要获取特定魔术命令的帮助,请在其名称后键入问号,例如 %timeit? 或 %%writefile?。

执行外部 Python 脚本。脚本中定义的变量在当前的 IPython 命名空间中可用。

# 假设 hello.py 包含: print('Hello from script!')
%run hello.py
# 输出:
# Hello from script!

将外部脚本中的代码加载到当前单元格中,以便编辑和执行。

# 假设 hello.py 包含: print('Hello from script!')
%load hello.py
# 单元格内容变为:
# # %load hello.py
# print('Hello from script!')

通过多次运行来衡量 Python 语句或表达式的执行时间,以提高准确性。既可以用作行魔术,也可以用作单元格魔术。

# 行魔术:
%timeit [x**2 for x in range(1000)]
# 输出:(例如)85.6 µs ± 1.2 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
# 单元格魔术:
%%timeit
result = []
for x in range(1000):
result.append(x**2)
# 输出:(例如)93.1 µs ± 2.5 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

测量单个语句的执行时间(对于不需要多次循环的长时间运行代码很有用)。

import time
%time time.sleep(1)
# 输出:(例如)Wall time: 1 s

显示当前会话的命令历史记录。使用像 -n 这样的标志来包含行号。

a = 10
b = 20
%history -n 1-2
# 输出:
# 1: a = 10
# 2: b = 20

%pwd 打印当前工作目录。%cd <directory> 更改当前工作目录。使用 %cd - 返回上一个目录。

%pwd
# 输出:(例如)/home/user/myproject
%cd ..
# 输出:(例如)/home/user
%pwd
# 输出:(例如)/home/user
%cd -
# 输出:(例如)/home/user/myproject

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

var_a = 'hello'
var_b = [1, 2, 3]
%who
# 输出: var_a var_b
%whos
# 输出:
# 变量 类型 数据/信息
# ----------------------------
# var_a str hello
# var_b list n=3

配置 Matplotlib 集成。%matplotlib inline 常用于 Jupyter Notebook/Lab 中,直接在输出单元格内渲染图表。其他后端(如 qt、notebook)可以启用交互式图表。

%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 100)
plt.plot(x, np.sin(x))
# 输出: [一个正弦波的静态图表出现在单元格下方]

加载 IPython 扩展,这些扩展可以提供额外的魔术命令或功能。一个流行的例子是用于运行 SQL 查询的 sql,或用于在代码执行前自动重新加载模块的 autoreload。

%load_ext autoreload
%autoreload 2
# 启用导入模块的自动重新加载

一个单元格魔术,将单元格的内容保存到指定的文件中。

%%writefile my_script.py
def greet(name):
print(f'Hello, {name}!')
greet('World')
# 输出: Writing my_script.py

用于使用系统 shell(在 Linux/macOS 上是 bash,在 Windows 上是 cmd)或使用 %%script <interpreter> 指定的任何其他解释器执行代码的单元格魔术。

# 使用 bash 的示例 (Linux/macOS)
%%bash
echo "Listing files:"
ls -l | head -n 3
# 输出:
# Listing files:
# total 8
# -rw-r--r-- 1 user user 60 Dec 15 10:30 my_script.py
# ...

管理环境变量。%env 列出所有变量,%env VAR 获取 VAR 的值,%env VAR=value 设置当前进程中 VAR 的值。

%env PATH
# 输出:(显示当前的 PATH 环境变量)
%env MY_VAR=test
# 将 MY_VAR 设置为 'test'
%env MY_VAR
# 输出: test

切换行魔术是否可以在不带前导 ’%’ 的情况下调用。为了清晰起见,通常建议明确使用 ’%’ 并保持 automagic OFF(默认通常是 ON)。使用 %automagic 0 禁用或 %automagic 1 启用。

你可以使用 IPython.core.magic 模块中的装饰器定义自己的魔术命令。这允许你将自定义工作流程封装到可重用的命令中。

from IPython.core.magic import register_line_magic
@register_line_magic
def hello_magic(line):
"""一个用于打招呼的简单行魔术。"""
name = line.strip() if line.strip() else 'World'
print(f"Hello, {name} from custom magic!")
# 现在你可以使用它了:
%hello_magic
# 输出: Hello, World from custom magic!
%hello_magic Alice
# 输出: Hello, Alice from custom magic!

类似的装饰器(@register_cell_magic、@register_line_cell_magic)也存在,用于创建其他类型的自定义魔术。