前言
很多人第一次听说 IPython,会以为它是 Python 自带的那个交互式解释器换了个名字。不是。python命令进入的 REPL(Read-Eval-Print Loop,读取-求值-打印循环)是标准解释器内置的;IPython 是一个第三方项目,需要单独安装才能用。它的定位是「增强版交互式 shell」:保留 REPL 的即时反馈,同时补上历史结果复用、魔术命令、Tab 补全、问号查文档、 调用系统命令这些日常高频能力。
本文把 IPython 相对标准 REPL 的主要增强逐项讲清,每一项都给出可复现的输入。需要注意: IPython 是第三方库,它的命令名、参数和输出格式会随版本调整,具体细节以 IPython 官方 文档为准。另外,Python 2.7 已于 2020 年 1 月 1 日停止维护;早期 IPython 曾支持 Python 2,当前版本面向 Python 3,本文全部按 Python 3 描述。
一、安装与启动
IPython 不在标准库里,第一步是安装。装好之后用ipython命令启动。
# 安装(第三方包)
python -m pip install ipython
# 启动交互式 shell
ipython启动后你会看到一个带编号提示符的界面,形如In [1]:。这个编号不是装饰,后面讲历史 结果时会用到它。如果你见过[1]这种方括号编号,那是 IPython 的标志性样式。
需要注意区分:IPython 提供的是命令行交互环境;Jupyter Notebook 是建立在 IPython内核之上的网页界面。两者共用同一套内核能力,但使用方式不同。
二、_与In/Out:把历史结果变成变量
标准 REPL 里只有一个下划线_能取到上一次的输出。IPython 把这件事做成了完整体系。 官方文档说明,下面这些名字始终存在:
| 名字 | 含义 |
|---|
_ | 上一次的输出 |
__ | 上上次的输出 |
___ | 上上上次的输出 |
_i、_ii、_iii | 上一条、上上条、上上上条输入 |
In/_ih | 所有输入的列表,In[n]是第 n 行输入 |
Out/_oh | 有返回值的行构成的字典,Out[n]是第 n 行的输出 |
_12、_i12 | 按编号取第 12 行的输出 / 输入 |
用法很直观:
# 适用于 Python 3.8+
# 下面这些是在 IPython 提示符里逐条输入的
# In [1]: 2 + 3
# Out[1]: 5
# In [2]: _ * 4
# Out[2]: 20 <- _ 是上一次输出 5输入历史也存在列表里,可以按编号取回重算:
# 适用于 Python 3.8+
# In [3]: In[1]
# Out[3]: '2 + 3' <- 拿回的是那行的输入文本
# In [4]: eval(In[1])
# Out[4]: 5这套机制配合调试非常省事:算出一个中间结果后,直接_接着算,不必再起一个变量名。
三、魔术命令(magics)
魔术命令是 IPython 的标志性功能,语法上以百分号开头。行魔术用单个%,作用于一行; 单元魔术用双百分号%%,作用于整个代码块。下面是官方文档里确认存在的常用命令。
| 命令 | 作用 |
|---|
%timeit | 多次重复执行一条语句并给出耗时统计 |
%run | 在当前会话里执行一个脚本文件 |
%who/%whos | 列出当前存在的交互式变量 |
%load | 把文件内容载入到当前单元格 |
%edit | 打开编辑器编辑代码 |
%history/%hist | 查看输入历史 |
%pdb | 出现异常时自动进入调试器 |
%debug | 进入事后调试 |
%prun | 用分析器运行代码 |
%cd/%pwd | 切换 / 显示当前工作目录 |
%env/%set_env | 查看 / 设置环境变量 |
%pip | 在会话里调用 pip 安装包 |
%matplotlib | 配置 matplotlib 的显示方式 |
%reset | 清空命名空间 |
%config | 查看或修改配置项 |
%psearch | 按模式搜索对象 |
几个最常用的例子:
In [1]: %timeit sum(range(1000))
# 会输出多次运行的耗时统计(均值、标准差、运行次数)
In [2]: %run script.py
# 相当于在当前命名空间里执行 script.py(而不是另起一个进程)
In [3]: %who
# 列出当前会话里定义了哪些变量
In [4]: %cd /tmp
# 切换当前工作目录关于%timeit要提醒一句:它给的是统计结果,受机器负载、解释器版本、数据规模影响 很大。看到某个数字之后不要直接当成普遍结论,更不要把它换算成「快了 N 倍」去宣传。 要比较两段代码,就在同一台机器、同一次会话里分别跑%timeit自己看。
%run和「用import导入脚本」也不一样:%run是在当前交互命名空间里执行文件内容, 文件里定义的变量会直接出现在会话中,适合边开发边调试。
四、叹号:在会话里调用系统命令
任何以!开头的输入行会被原样交给底层操作系统执行(去掉那个!)。这是 IPython 里最常用的「顺手能力」之一。
In [1]: !ls
# 在当前目录下执行 ls,输出直接显示
In [2]: !echo hello
hello如果想把命令的输出捕获成 Python 变量而不是直接打印,就用两个叹号!!,或者用%sx魔术命令:
# 适用于 Python 3.8+
# In [3]: files = !ls
# In [4]: len(files) <- files 是一个列表,每行一个元素需要注意几个边界:!只在行首起作用,写在表达式中间不会触发;!调用的是系统 命令,可移植性取决于运行环境;!!捕获的输出不能直接赋值的那类限制,官方文档有专门 说明,用之前建议查一下。
五、Tab 补全与问号查文档
这两项是 IPython 日常使用频率最高的功能。
Tab 补全:输入对象名的一部分再按 Tab,会列出可用的属性、方法、模块成员。
问号查文档:?word或word?会打印出对象的详细信息——类型、值、docstring、 函数签名参数等。想看得更全(包括能取到的源码)就用两个问号??word或word??。
# 适用于 Python 3.8+
# In [1]: str.split?
# -> 显示 str.split 的签名和文档字符串
# In [2]: str.split??
# -> 在信息里额外带上能取到的源码
# In [3]: %timeit?
# -> 魔术命令本身也能用问号查它的用法再配合内置的dir()和help(),你在终端里基本不用离开就能搞清一个陌生 API 怎么用。 这也是本文反复强调「以官方文档为准」时最顺手的一条路径:?和??给出的就是该对象 自带的文档。
六、它和标准 REPL、和 Jupyter 的关系
三种环境的关系可以用一张表说清:
| 环境 | 来源 | 主要用途 |
|---|
python(标准 REPL) | 标准解释器自带 | 快速验证一两行代码 |
| IPython | 第三方,需安装 | 交互式探索、调试、脚本实验 |
| Jupyter Notebook | 第三方,基于 IPython 内核 | 图文混排的分析与教学 |
如果你只是想试一行语法,标准 REPL 足够了;如果你要在终端里反复试验、调试、跑脚本, IPython 的增强功能收益明显;如果你要把代码、输出和说明放在一起交付,则用 Jupyter。
常见坑点
坑点 1:以为 IPython 是标准库自带的。
❌ 错误做法:
# 在没装过 IPython 的机器上直接敲
ipython
# command not found✅ 正确做法:
python -m pip install ipython
ipython它是第三方包,必须先安装。
坑点 2:把%timeit的输出当普遍结论。
❌ 错误做法:
在同一次运行里看到某个写法数字更小,就写进文档说「快了好几倍」✅ 正确做法:
在同一台机器、同一次会话里分别跑 %timeit,只比较相对趋势,
并说明测试条件,不给出脱离环境的倍数坑点 3:以为%run等于import。
❌ 错误做法:
# 适用于 Python 3.8+
# 指望 %run 像 import 那样产生一个模块对象来引用
# In [1]: %run utils.py
# In [2]: utils.func() # NameError,没有 utils 这个名字✅ 正确做法:
# 适用于 Python 3.8+
# %run 是把文件内容在当前命名空间里执行
# In [1]: %run utils.py
# In [2]: func() # 文件里定义的函数直接可用要模块对象就用import utils。
坑点 4:在表达式中间用!。
❌ 错误做法:
In [1]: x = 1 + !echo hi
# 不会按预期触发 shell 调用✅ 正确做法:
# 适用于 Python 3.8+
# In [1]: out = !echo hi
# In [2]: out!只在行首生效,要捕获输出就用行首的!或!!。
坑点 5:把_当成普通变量名到处用。
❌ 错误做法:
# 适用于 Python 3.8+
# In [1]: _ = 100
# In [2]: 1 + 1
# Out[2]: 2
# In [3]: _ <- 想拿 100,结果拿到 2✅ 正确做法:
# 适用于 Python 3.8+
# In [1]: total = 100 # 需要长期保存就起个正常名字_由 IPython 自动覆盖,别拿它存需要长期保留的值。
坑点 6:用%reset之后以为文件或环境被清了。
❌ 错误做法:
In [1]: %reset
# 以为磁盘上的数据和已安装的包都没了✅ 正确做法:
%reset 清的是当前会话的命名空间(变量),不删文件、不卸包需要保留某些变量时,用它的选择性重置选项,具体参数以官方文档为准。
坑点 7:在虚拟环境外启动 IPython,装包装错地方。
❌ 错误做法:
# 没激活虚拟环境就装包,包装到了全局环境
python -m pip install requests✅ 正确做法:
# 先激活项目虚拟环境,再启动 IPython 和装包
# Linux / macOS 下激活后
python -m pip install requests
# 确认当前用的是哪个解释器,路径应指向项目虚拟环境
python -c "import sys; print(sys.executable)"包装在哪个环境里,取决于启动 IPython 时用的是哪个解释器;用sys.executable打印 路径即可确认。
坑点 8:把交互会话里跑通的结果当成可复现的脚本。
❌ 错误做法:
在 IPython 里零散敲了一堆语句,跑出结果后直接说「程序是对的」✅ 正确做法:
# 适用于 Python 3.8+
# 把验证过的语句按依赖顺序写进 .py 文件,从空环境重新跑一遍交互环境会残留状态,脚本从干净环境跑通才算数。
总结
| 能力 | 标准 REPL | IPython |
|---|
上一次输出_ | 有 | 有,还有__、___ |
| 输入/输出历史对象 | 无 | In/Out/_ih/_oh |
| 魔术命令 | 无 | %timeit、%run、%who等 |
| 调用系统命令 | 无 | !与!! |
| Tab 补全 | 有限 | 完整 |
?/??查文档 | 无(只能用help()) | 有 |
| 安装方式 | 自带 | 第三方,需pip install ipython |
IPython 的价值在于把「试一段代码」这件事做得顺手:结果能直接复用,历史能翻回来, 命令能顺手查文档,还能随时切出去执行系统命令。它是第三方项目,装之前先确认环境, 用的时候记得版本差异——具体命令与参数以 IPython 官方文档为准。