重要提示

此文档涵盖 IPython 6.0 及更高版本。从 6.0 版本开始,IPython 不再支持与低于 3.3 的 Python 版本(包括所有版本的 Python 2.7)的兼容性。

如果您正在寻找与 Python 2.7 兼容的 IPython 版本,请使用 IPython 5.x LTS 版本,并参阅其文档(LTS 是长期支持版本)。

IPython 参考

命令行用法

使用命令启动 IPython

$ ipython [options] files

如果在不带任何选项的情况下调用它,它将执行文件并退出,将剩余参数传递给脚本,就像您使用 python 指定相同的命令一样。您可能需要在传递给脚本的参数之前指定 --,以防止 IPython 尝试解析它们。如果您添加 -i 标志,它会让您进入解释器,同时仍会确认您可能在 ipython_config.py 中设置的任何选项。此行为不同于标准 Python,当被调用为 python -i 时,它只会执行一个文件并忽略您的配置设置。

请注意,某些配置选项在命令行中不可用,仅仅是因为它们在这里不实用。有关它们的详细信息,请查看您的配置文件。每个配置文件都有单独的配置文件,文件看起来像 ipython_config.pyipython_config_frontendname.py。配置文件目录看起来像 profile_profilename,通常安装在 IPYTHONDIR 目录中,默认为 $HOME/.ipython。对于 Windows 用户,HOME 在大多数情况下解析为 C:\Users{YourUserName}

命令行选项

要查看 IPython 接受的选项,请使用 ipython --help(并且您可能应该通过分页器(例如 ipython --help | less)运行输出以方便阅读)。这将显示所有具有用于控制它们的单字别名的选项,但 IPython 允许您通过传递完整类名和相应值从命令行配置其所有对象;键入 ipython --help-all 以查看此完整列表。例如

$ ipython --help-all
<...snip...>
--matplotlib=<CaselessStrEnum> (InteractiveShellApp.matplotlib)
    Default: None
    Choices: ['auto', 'gtk3', 'gtk4', 'inline', 'nbagg', 'notebook', 'osx', 'qt', 'qt5', 'qt6', 'tk', 'wx']
    Configure matplotlib for interactive use with the default matplotlib
    backend.
<...snip...>

表示以下内容

$ ipython --matplotlib qt

等效于

$ ipython --InteractiveShellApp.matplotlib='qt'

请注意,在第二种形式中,您必须使用等号,因为该表达式被评估为实际的 Python 赋值。虽然在上述示例中,简短形式更方便,但只有最常见的选项具有简短形式,而 IPython 中的任何可配置变量都可以使用长形式在命令行中设置。如果您希望永久设置这些选项,则此长形式与配置文件中使用的语法相同。

交互式使用

IPython 旨在作为标准交互式解释器的替代品。因此,任何有效的 Python 代码都应该在 IPython 下正常执行(不符合这种情况的情况应报告为错误)。但是,它提供了许多在标准 Python 提示符下不可用的功能。以下是这些功能的列表。

Windows 用户注意

不幸的是,Windows 使用 \ 字符作为路径分隔符。这是一个糟糕的选择,因为 \ 也表示大多数现代编程语言(包括 Python)中的转义字符。因此,如果您在 \ 方面遇到问题,建议使用“/”字符。但是,在 Windows 命令中,“/”标记选项,因此您不能将其用于根目录。这意味着必须以人为的方式键入从根目录开始的路径,例如:%copy \opt/foo/bar.txt \tmp

魔术命令系统

IPython 将把第一个字符为 % 的任何行视为对“魔术”函数的特殊调用。这些允许您控制 IPython 本身的行为,以及许多系统类型功能。它们都以 % 字符为前缀,但参数不带括号或引号。

%% 开头的行表示单元格魔术:它们不仅将当前行的其余部分作为参数,还将当前执行块中它们下面的所有行作为参数。实际上,单元格魔术可以对其接收的输入进行任意修改,甚至根本不必是有效的 Python 代码。它们将整个块作为一个字符串接收。

作为行魔术示例,%cd 魔术与同名操作系统命令的工作方式相同

In [8]: %cd
/home/fperez

以下内容在单元格模式下使用内置 %timeit

In [10]: %%timeit x = range(10000)
    ...: min(x)
    ...: max(x)
    ...:
518 µs ± 4.39 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

在这种情况下,x = range(10000) 被调用为行参数,并且带有 min(x)max(x) 的块被调用为单元格主体。%timeit 魔术接收两者。

如果你启用了“自动魔法”(默认情况下已启用),则无需为行魔法明确输入单个 %;IPython 将扫描其内部魔法函数列表,并在存在时调用一个函数。启用自动魔法后,你可以直接输入 cd mydir 以转到目录“mydir”

In [9]: cd mydir
/home/fperez/mydir

单元格魔法始终需要显式的 %% 前缀,自动魔法调用仅适用于行魔法。

自动魔法系统在名称搜索中具有最低的优先级,因此你可以随意使用与魔法命令同名的变量。如果魔法命令被变量“遮蔽”,则需要显式的 % 前缀才能使用它

In [1]: cd ipython     # %cd is called by automagic
/home/fperez/ipython

In [2]: cd=1           # now cd is just a variable

In [3]: cd ..          # and doesn't work as a function anymore
File "<ipython-input-3-9fedb3aff56c>", line 1
  cd ..
      ^
SyntaxError: invalid syntax


In [4]: %cd ..         # but %cd always works
/home/fperez

In [5]: del cd     # if you remove the cd variable, automagic works again

In [6]: cd ipython

/home/fperez/ipython

行魔法(如果它们返回一个值)可以使用语法 l = %sx ls 分配给一个变量(在此特定情况下,它将以 Python 列表的形式返回 ls 的结果)。有关更多信息,请参见下文

输入 %magic 以获取更多信息,包括随时可用的所有魔法函数列表及其文档字符串。你还可以输入 %magic_function_name?(有关“?”系统的信息,请参见下文)以获取你感兴趣的任何特定魔法函数的信息。

用于 IPython.core.magic 模块的 API 文档包含当前所有可用魔法命令的完整文档字符串。

另请参见

内置魔术命令

IPython 中默认可用的行魔法和单元格魔法列表

定义自定义魔法

如何定义和注册其他魔法函数

访问标准 Python 帮助

只需输入 help() 即可访问 Python 的标准帮助系统。你还可以输入 help(object) 以获取有关给定对象的的信息,或输入 help('keyword') 以获取有关关键字的信息。你可能需要配置 PYTHONDOCS 环境变量才能让此功能正常工作。

动态对象信息

输入 ?wordword? 会打印有关对象的详细信息。如果对象中的某些字符串太长(例如函数签名),则会为了简洁起见而将其剪切到中心。此系统可以访问变量类型和值、文档字符串、函数原型和其他有用的信息。

如果信息不适合终端,则会在分页器中显示该信息(如果可用,则为 less,否则为基本的内部分页器)。

输入 ??wordword?? 可以访问完整信息,包括可能的源代码。长字符串不会被剪切。

以下魔法函数对于收集有关工作环境的信息特别有用

  • %pdoc <object>:打印对象的文档字符串(如果太长,则通过分页器打印)。如果给定的对象是一个类,它将打印类和构造函数的文档字符串。

  • %pdef <object>:打印任何可调用对象的调用签名。如果对象是一个类,则打印构造函数信息。

  • %psource <object>:打印(或如果太长,则通过分页器运行)对象的源代码。

  • %pfile <object>:通过分页器显示定义对象的整个源文件,在对象定义开始的行处打开它。

  • %who/%whos:这些函数提供有关你交互定义的标识符的信息(不是你在配置文件中加载或定义的内容)。%who 仅打印标识符列表,而 %whos 打印一个表格,其中包含有关每个标识符的一些基本详细信息。

动态对象信息函数(?/??,%pdoc%pfile%pdef%psource)适用于对象属性,以及直接适用于变量。例如,在执行 import os 之后,你可以使用 os.path.abspath??

命令行补全

在任何时候,按 TAB 键将补全任何可用的 python 命令或变量名,如果没有明确的命令或变量名,它将向你显示可能的补全列表。如果当前目录中没有与 python 名称匹配的名称,它还将补全文件名。

搜索命令历史记录

IPython 提供了两种方法来搜索以前的输入,从而减少重复输入的需要

  1. 开始输入,然后使用向上和向下箭头键(或 Ctrl-pCtrl-n)仅搜索与你到目前为止输入的内容匹配的历史记录项。

  2. Ctrl-r:打开搜索提示。开始输入,系统将在你的历史记录中搜索包含你到目前为止输入的内容的行,尽可能地完成输入。

IPython 将在退出时保存你的输入历史记录,并在下次重新启动时重新加载它。默认情况下,历史记录文件名为 .ipython/profile_name/history.sqlite

自动缩进

从 5.0 开始,IPython 使用 prompt_toolkit 替换 readline,因此它可以识别以“:”结尾的行并缩进下一行,同时在“raise”或“return”后自动取消缩进,并支持真正的多行编辑以及编辑期间的语法着色。

此功能不再使用 readline 库,因此它不会遵循你的 ~/.inputrc 配置(或你的 INPUTRC 环境变量指向的任何文件)。

特别是,如果你想将输入模式更改为 vi,你需要设置 IPython 的 TerminalInteractiveShell.editing_mode 配置选项。

会话记录和恢复

你可以通过使用命令行开关 --logfile=foo.py 启动 IPython(请参见此处)或使用魔术函数 %logstart随时激活日志记录来记录会话中的所有输入。

稍后可以通过将日志文件作为脚本运行来重新加载它们,IPython 将尝试通过执行其中的所有行来“重放”日志,从而恢复以前会话的状态。此功能并不完美,但在许多情况下仍然很有用。

日志文件还可以用作在实验过程中编写的任何代码的永久记录。日志文件是常规文本文件,您可以在稍后使用您最喜欢的文本编辑器打开它们来提取代码或在使用它们重现会话之前“清理”它们。

用于在会话中间激活日志记录的 %logstart 函数的使用方式如下

%logstart [log_name [log_mode]]

如果未给出名称,则默认为当前工作目录中名为“ipython_log.py”的文件,处于“rotate”模式(见下文)。

“%logstart name”保存到“backup”模式中的文件“name”。它保存到该点为止的历史记录,然后继续记录。

%logstart 采用第二个可选参数:记录模式。这可以是其中之一(请注意,模式没有加引号)

  • [over:] 覆盖现有的 log_name。

  • [backup:] 重命名(如果存在)为 log_name~ 并启动 log_name。

  • [append:] 好吧,它说明了这一点。

  • [rotate:] 创建轮换日志 log_name.1~、log_name.2~ 等。

向“%logstart”魔术添加“-o”标志(如“%logstart -o [log_name [log_mode]]”)还将日志文件中的 iPython 输出包括在内。

函数 %logoff%logon 允许您暂时停止和恢复记录到先前使用 %logstart 启动的文件。如果您尝试在记录开始之前使用它们,它们将失败(并提供解释)。

系统 shell 访问

! 字符开头的任何输入行都会原样传递(当然,除了 !)给底层操作系统。例如,键入 !ls 将在当前目录中运行“ls”。

手动捕获命令输出和魔术输出

您可以使用语法 myfiles = !ls 将系统命令的结果分配给 Python 变量。同样,魔术的结果(只要它返回一个值)可以分配给一个变量。例如,语法 myfiles = %sx ls 等于上述系统命令示例(%sx 魔术运行 shell 命令并捕获输出)。每个命令都会从 stdout 获取机器可读的输出(例如,不带颜色),并按换行符拆分。要明确获取此类输出而不分配给变量,请使用两个感叹号(!!ls)或 %sx 魔术命令,但不进行分配。(但是,!! 命令不能分配给变量。)

此示例中捕获的列表具有一些便利功能。 myfiles.nmyfiles.s 分别返回以换行符或空格分隔的字符串。 myfiles.p 从列表项生成 路径对象。有关详细信息,请参见 字符串列表

IPython 还允许您在进行系统调用时扩展 python 变量的值。将变量或表达式包装在大括号 {} 中

In [1]: pyvar = 'Hello world'
In [2]: !echo "A python variable: {pyvar}"
A python variable: Hello world
In [3]: import math
In [4]: x = 8
In [5]: !echo {math.factorial(x)}
40320

对于简单的情况,您还可以将 $ 前置到变量名称

In [6]: !echo $sys.argv
[/home/fperez/usr/bin/ipython]
In [7]: !echo "A system variable: $$HOME"  # Use $$ for literal $
A system variable: /home/fperez

请注意,$$ 用于表示一个文字 $

系统命令别名

魔术函数 %alias 允许您定义实际上是系统 shell 命令的魔术函数。这些别名可以有参数。

%alias alias_name cmd 将 ‘alias_name’ 定义为 ‘cmd’ 的别名

然后,键入 alias_name params 将执行系统命令 ‘cmd params’(来自您的底层操作系统)。

您还可以使用 %s 规范符(每个参数一个)定义带参数的别名。以下示例将 parts 函数定义为命令 echo first %s second %s 的别名,其中每个 %s 将被 %parts 调用中的位置参数替换

In [1]: %alias parts echo first %s second %s
In [2]: parts A B
first A second B
In [3]: parts A
ERROR: Alias <parts> requires 2 arguments, 1 given.

如果在没有参数的情况下调用,%alias 将打印当前定义的别名表。

魔术 %rehashx 允许您将整个 $PATH 加载为 ipython 别名。有关更多详细信息,请参阅其文档字符串。

递归重新加载

IPython.lib.deepreload 模块允许您递归重新加载模块:对任何依赖项所做的更改都将在无需退出时重新加载。要开始使用它,请执行

from IPython.lib.deepreload import reload as dreload

详细且带颜色的异常回溯打印输出

IPython 提供了查看非常详细的异常回溯的选项,这在调试大型程序时特别有用。您可以使用 %run 函数运行任何 Python 文件,以从这些详细的回溯中受益。此外,普通和详细的回溯都可以着色(如果您的终端支持),这使得它们在视觉上更容易解析。

有关详细信息,请参阅魔术 %xmode%colors 函数。

这些功能基本上是 Ka-Ping Yee 的 cgitb 模块的终端版本,现在是标准 Python 库的一部分。

输入缓存系统

IPython 提供带输入和输出缓存(也称为“输入历史记录”)的编号提示(In/Out)。除了通常的箭头键召回之外,所有输入都会被保存并可以作为变量检索,此外,%rep 魔术命令将历史记录条目带到下一条命令行进行编辑。

以下变量始终存在

  • _i_ii_iii:存储上一个、上上一个和下下个输入。

  • In_ih:所有输入的列表;_ih[n] 是第 n 行的输入。如果你用自己的变量覆盖了 In,你可以通过简单的 In=_ih 重新赋值给内部列表。

此外,会动态创建名为 _i<n> 的全局变量(<n> 是提示符计数器),因此 _i<n> == _ih[<n>] == In[<n>]

例如,你在提示符 14 中键入的内容可作为 _i14_ih[14]In[14] 使用。

这允许你通过打印多行交互式提示符来轻松地剪切和粘贴它们:它们像一个干净的字符串一样打印,没有提示符字符。你还可以像普通变量一样操作它们(它们是字符串),修改或执行它们。

你还可以使用魔术 %rerun%macro 函数轻松地重新执行多行输入。宏系统还允许你重新执行包含魔术函数调用的前几行(需要特殊处理)。键入 %macro? 了解更多关于宏系统的详细信息。

历史函数 %history 允许你通过打印一系列 _i 变量来查看输入历史的任何部分。

你还可以通过键入 %hist -g somestring 来搜索(‘grep’)你的历史记录。这对于搜索 URL、IP 地址等非常方便。你可以使用 %recall 命令将 ‘%hist -g’ 列出的历史记录调出进行编辑,或者使用 %rerun 立即运行它们。

输出缓存系统

对于从操作返回的输出,存在一个类似于输入缓存的系统,但使用 _ 而不是 _i。只有产生结果的操作(例如,不是赋值)才会被缓存。如果你熟悉 Mathematica,IPython 的 _ 变量的行为与 Mathematica 的 % 变量完全相同。

以下变量始终存在

  • [_](单个下划线):存储上一个输出,就像 Python 的默认解释器一样。

  • [__](两个下划线):上上一个。

  • [___](三个下划线):下下个。

此外,会动态创建名为 _<n> 的全局变量(<n> 是提示符计数器),因此输出 <n> 的结果始终可用作 _<n>(不要使用尖括号,只需使用数字,例如 _21)。

这些变量还存储在全局字典中(不是列表,因为它只包含返回结果的行条目),可以在名称 _oh 和 Out(类似于 _ih 和 In)下找到。因此,第 12 行的输出可以获取为 _12Out[12]_oh[12]。如果你不小心覆盖了 Out 变量,可以通过在提示符处键入 Out=_oh 来恢复它。

显然,此系统可能会对你的系统造成较大的内存需求,因为它阻止 Python 的垃圾回收器删除任何先前计算的结果。你可以使用配置选项 InteractiveShell.cache_size 控制在内存中保留多少结果。如果你将它设置为 0,则会禁用输出缓存。你还可以使用 %reset%xdel 魔术从内存中清除大型项目。

目录历史

访问目录的历史记录保存在全局列表 _dh 中,可以使用魔术 %cd 命令转到该列表中的任何条目。 %dhist 命令允许您查看此历史记录。执行 cd -<TAB> 以方便地查看目录历史记录。

自动括号和引号

这些功能改编自 Nathan Gray 的 LazyPython。它们旨在减少常见情况下的输入量。

可调用对象(即函数、方法等)可以像这样调用(注意参数之间的逗号)

In [1]: callable_ob arg1, arg2, arg3
------> callable_ob(arg1, arg2, arg3)

注意

此功能默认情况下处于禁用状态。要启用它,请使用 %autocall 魔术命令。但是,带有特殊前缀的以下命令始终有效。

您可以使用“/”作为行中的第一个字符来强制使用自动括号。例如

In [2]: /globals # becomes 'globals()'

请注意,“/”必须是行中的第一个字符!这不起作用

In [3]: print /globals # syntax error

在大多数情况下,自动算法应该起作用,因此您很少需要显式调用 /。一个值得注意的例外是,如果您尝试使用元组列表作为参数调用函数(括号会混淆 IPython)

In [4]: zip (1,2,3),(4,5,6) # won't work

但这将起作用

In [5]: /zip (1,2,3),(4,5,6)
------> zip ((1,2,3),(4,5,6))
Out[5]: [(1, 4), (2, 5), (3, 6)]

IPython 会通过显示以 ---> 为前缀的新命令行来告诉您它已更改您的命令行。

您可以使用 ,; 作为行中的第一个字符来强制自动引用函数的参数。例如

In [1]: ,my_function /home/me  # becomes my_function("/home/me")

如果您使用“;”,则整个参数将被引用为一个字符串,而“,”则在空格上拆分

In [2]: ,my_function a b c    # becomes my_function("a","b","c")

In [3]: ;my_function a b c    # becomes my_function("a b c")

请注意,“,”或“;”必须是行中的第一个字符!这不起作用

In [4]: x = ,my_function /home/me # syntax error

将 IPython 作为默认 Python 环境

Python 尊重环境变量 PYTHONSTARTUP,并在启动时执行此变量引用的文件。如果您将以下代码放在该文件的末尾,那么每当您启动 Python 时,IPython 都会成为您的工作环境

import os, IPython
os.environ['PYTHONSTARTUP'] = ''  # Prevent running this again
IPython.start_ipython()
raise SystemExit

raise SystemExit 在 Python 完成时需要退出 Python,否则您将返回到正常的 Python >>> 提示符。

这可能对管理多个 Python 版本且不想拥有多个 IPython 版本的开发人员有用。请注意,在此模式下,无法向 IPython 传递任何命令行选项,因为这些选项首先被 Python 本身捕获。

嵌入 IPython

您可以在程序中的任何位置使用以下命令启动常规 IPython 会话

import IPython
IPython.start_ipython(argv=[])

这将加载 IPython 配置、启动文件以及所有内容,就像它是一个正常的 IPython 会话一样。有关从 python 运行 IPython 时设置配置选项的信息,请参阅 从 Python 运行 IPython

还可以在 Python 代码中的命名空间中嵌入 IPython shell。这允许您动态评估代码的状态、使用变量、分析变量等。例如,如果您运行以下代码段

import IPython

a = 42
IPython.embed()

在 IPython shell 中,您将 a 重新分配给 23 以进行某种进一步测试,然后您可以退出

>>> IPython.embed()
Python 3.6.2 (default, Jul 17 2017, 16:44:45)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.0.dev -- An enhanced Interactive Python. Type '?' for help.

In [1]: a = 23

In [2]: exit()

退出并打印 a 后,将显示值 23

In: print(a)
23

需要注意的是,嵌入式 IPython shell 中运行的代码不会更改代码和变量的状态,除非 shell 包含在全局名称空间中。在上述示例中,a 会发生更改,因为这是正确的。

为了进一步说明这一点,请考虑以下示例

import IPython
def do():
    a = 42
    print(a)
    IPython.embed()
    print(a)

现在,如果调用该函数并完成状态更改(如上所述),将打印值 42。同样,这是因为它不在全局名称空间中

do()

使用上述代码运行文件会导致以下会话

>>> do()
42
Python 3.6.2 (default, Jul 17 2017, 16:44:45)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.0.dev -- An enhanced Interactive Python. Type '?' for help.

In [1]: a = 23

In [2]: exit()
42

注意

目前,无法在 IPython 内部嵌入 IPython。在 IPython 外部运行以下代码示例。

此功能允许您通过简单的函数调用轻松地在代码中的任何位置拥有一个功能齐全的 Python 环境,用于执行对象内省。在某些情况下,简单的打印语句就足够了,但如果您需要对代码片段进行更详细的分析,此功能将非常有价值。

在科学计算情况下,此功能也很有用,在这种情况下,通常需要执行一些自动的计算密集型部分,然后停止查看数据、绘图等。打开一个 IPython 实例将使您能够完全访问您的数据和函数,并且一旦您完成交互部分(可能稍后多次停止,根据需要),您可以恢复程序执行。

以下代码片段是您需要在 Python 程序中包含的最低限度,才能使此功能正常工作(详细示例将在后面给出)

from IPython import embed

embed() # this call anywhere in your program will start IPython

您还可以嵌入 IPython 内核,以便与 qtconsole 等一起使用,方法是 IPython.embed_kernel()。这应该以相同的方式工作,但您可以连接外部前端(ipython qtconsoleipython console),而不是在终端中与之交互。

您甚至可以在使用“%run <filename>”在 IPython 交互式提示符下运行的代码中运行嵌入式实例。由于很容易迷失在何处(在您的顶级 IPython 中或在您的嵌入式 IPython 中),因此在这种情况下最好为嵌入式实例设置不同的输入/输出提示。下面的代码示例对此进行了说明。

您还可以在程序中拥有多个 IPython 实例并分别打开它们,例如为数据呈现设置不同的选项。如果您多次关闭并打开同一个实例,其提示符计数器将从每次执行简单地继续到下一次执行。

请查看 embed 模块中的文档字符串,以获取有关此系统使用的更多详细信息。

以下示例文件说明了如何使用嵌入功能,它在示例目录中作为 embed_class_long.py 提供。它应该相当不言自明

#!/usr/bin/env python
"""An example of how to embed an IPython shell into a running program.

Please see the documentation in the IPython.Shell module for more details.

The accompanying file embed_class_short.py has quick code fragments for
embedding which you can cut and paste in your code once you understand how
things work.

The code in this file is deliberately extra-verbose, meant for learning."""

# The basics to get you going:

# IPython injects get_ipython into builtins, so you can know if you have nested
# copies running.

# Try running this code both at the command line and from inside IPython (with
# %run example-embed.py)

from IPython.terminal.prompts import Prompts, Token
from traitlets.config.loader import Config

class CustomPrompt(Prompts):

    def in_prompt_tokens(self):

        return [
            (Token.Prompt, 'In <'),
            (Token.PromptNum, str(self.shell.execution_count)),
            (Token.Prompt, '>: '),
            ]

    def out_prompt_tokens(self):
        return [
            (Token.OutPrompt, 'Out<'),
            (Token.OutPromptNum, str(self.shell.execution_count)),
            (Token.OutPrompt, '>: '),
        ]
 

try:
    get_ipython
except NameError:
    nested = 0
    cfg = Config()
    cfg.TerminalInteractiveShell.prompts_class=CustomPrompt
else:
    print("Running nested copies of IPython.")
    print("The prompts for the nested copy have been modified")
    cfg = Config()
    nested = 1

# First import the embeddable shell class
from IPython.terminal.embed import InteractiveShellEmbed

# Now create an instance of the embeddable shell. The first argument is a
# string with options exactly as you would type them if you were starting
# IPython at the system command line. Any parameters you want to define for
# configuration can thus be specified here.
ipshell = InteractiveShellEmbed(config=cfg,
                       banner1 = 'Dropping into IPython',
                       exit_msg = 'Leaving Interpreter, back to program.')

# Make a second instance, you can have as many as you want.
ipshell2 = InteractiveShellEmbed(config=cfg,
                        banner1 = 'Second IPython instance.')

print('\nHello. This is printed from the main controller program.\n')

# You can then call ipshell() anywhere you need it (with an optional
# message):
ipshell('***Called from top level. '
        'Hit Ctrl-D to exit interpreter and continue program.\n'
        'Note that if you use %kill_embedded, you can fully deactivate\n'
        'This embedded instance so it will never turn on again')

print('\nBack in caller program, moving along...\n')

#---------------------------------------------------------------------------
# More details:

# InteractiveShellEmbed instances don't print the standard system banner and
# messages. The IPython banner (which actually may contain initialization
# messages) is available as get_ipython().banner in case you want it.

# InteractiveShellEmbed instances print the following information every time they
# start:

# - A global startup banner.

# - A call-specific header string, which you can use to indicate where in the
# execution flow the shell is starting.

# They also print an exit message every time they exit.

# Both the startup banner and the exit message default to None, and can be set
# either at the instance constructor or at any other time with the
# by setting the banner and exit_msg attributes.

# The shell instance can be also put in 'dummy' mode globally or on a per-call
# basis. This gives you fine control for debugging without having to change
# code all over the place.

# The code below illustrates all this.


# This is how the global banner and exit_msg can be reset at any point
ipshell.banner2 = 'Entering interpreter - New Banner'
ipshell.exit_msg = 'Leaving interpreter - New exit_msg'

def foo(m):
    s = 'spam'
    ipshell('***In foo(). Try %whos, or print s or m:')
    print('foo says m = ',m)

def bar(n):
    s = 'eggs'
    ipshell('***In bar(). Try %whos, or print s or n:')
    print('bar says n = ',n)
    
# Some calls to the above functions which will trigger IPython:
print('Main program calling foo("eggs")\n')
foo('eggs')

# The shell can be put in 'dummy' mode where calls to it silently return. This
# allows you, for example, to globally turn off debugging for a program with a
# single call.
ipshell.dummy_mode = True
print('\nTrying to call IPython which is now "dummy":')
ipshell()
print('Nothing happened...')
# The global 'dummy' mode can still be overridden for a single call
print('\nOverriding dummy mode manually:')
ipshell(dummy=False)

# Reactivate the IPython shell
ipshell.dummy_mode = False

print('You can even have multiple embedded instances:')
ipshell2()

print('\nMain program calling bar("spam")\n')
bar('spam')

print('Main program finished. Bye!')

一旦您了解了系统的功能,就可以在程序中使用以下代码片段,这些代码片段已准备好剪切和粘贴

"""Quick code snippets for embedding IPython into other programs.

See embed_class_long.py for full details, this file has the bare minimum code for
cut and paste use once you understand how to use the system."""

#---------------------------------------------------------------------------
# This code loads IPython but modifies a few things if it detects it's running
# embedded in another IPython session (helps avoid confusion)

try:
    get_ipython
except NameError:
    banner=exit_msg=''
else:
    banner = '*** Nested interpreter ***'
    exit_msg = '*** Back in main IPython ***'

# First import the embed function
from IPython.terminal.embed import InteractiveShellEmbed
# Now create the IPython shell instance. Put ipshell() anywhere in your code
# where you want it to open.
ipshell = InteractiveShellEmbed(banner1=banner, exit_msg=exit_msg)

#---------------------------------------------------------------------------
# This code will load an embeddable IPython shell always with no changes for
# nested embededings.

from IPython import embed
# Now embed() will open IPython anywhere in the code.

#---------------------------------------------------------------------------
# This code loads an embeddable shell only if NOT running inside
# IPython. Inside IPython, the embeddable shell variable ipshell is just a
# dummy function.

try:
    get_ipython
except NameError:
    from IPython.terminal.embed import InteractiveShellEmbed
    ipshell = InteractiveShellEmbed()
    # Now ipshell() will open IPython anywhere in the code
else:
    # Define a dummy ipshell() so the same code doesn't crash inside an
    # interactive IPython
    def ipshell(): pass

使用 Python 调试器 (pdb)

通过 pdb 运行整个程序

Python 调试器 pdb 是一个功能强大的交互式调试器,它允许你逐步执行代码、设置断点、监视变量等。IPython 使得在 pdb 的控制下启动任何脚本变得非常容易,无论你是否将其包装到“main()”函数中。为此,只需在 IPython 提示符下键入 %run -d myscript。有关更多详细信息(包括如何控制 pdb 首先停止执行的位置),请参阅 %run 命令的文档。

有关 pdb 调试器使用的更多信息,请参阅 Python 文档中的 调试器命令

IPython 通过一些有用的附加功能扩展了调试器,例如对回溯进行着色。调试器将采用为 IPython 选择的配色方案。

where 命令也已扩展为采用要显示的上下文行数作为参数。这允许在浅层堆栈跟踪中显示许多行上下文

In [5]: def foo(x):
...:     1
...:     2
...:     3
...:     return 1/x+foo(x-1)
...:     5
...:     6
...:     7
...:

In[6]: foo(1)
# ...
ipdb> where 8
<ipython-input-6-9e45007b2b59>(1)<module>
----> 1 foo(1)

<ipython-input-5-7baadc3d1465>(5)foo()
    1 def foo(x):
    2     1
    3     2
    4     3
----> 5     return 1/x+foo(x-1)
    6     5
    7     6
    8     7

> <ipython-input-5-7baadc3d1465>(5)foo()
    1 def foo(x):
    2     1
    3     2
    4     3
----> 5     return 1/x+foo(x-1)
    6     5
    7     6
    8     7

而在较浅的堆栈跟踪中显示较少的上下文

ipdb> where 1
<ipython-input-13-afa180a57233>(1)<module>
----> 1 foo(7)

<ipython-input-5-7baadc3d1465>(5)foo()
----> 5     return 1/x+foo(x-1)

<ipython-input-5-7baadc3d1465>(5)foo()
----> 5     return 1/x+foo(x-1)

<ipython-input-5-7baadc3d1465>(5)foo()
----> 5     return 1/x+foo(x-1)

<ipython-input-5-7baadc3d1465>(5)foo()
----> 5     return 1/x+foo(x-1)

事后调试

当异常发生时进入调试器对于找到细微错误的根源非常有用,因为 pdb 在触发异常的代码点打开,并且当你的程序在此点“死亡”时,所有数据仍然可用,你可以上下遍历堆栈帧并了解问题的根源。

异常发生后,你可以使用 %debug 魔术命令来启动事后调试。IPython 还可以在你代码触发未捕获异常时每次调用调试器。此功能可以使用 %pdb 魔术命令切换,或者你可以使用 --pdb 选项启动 IPython。

对于 IPython 之外的程序中的事后调试器,将以下行放在“main”例程的顶部

import sys
from IPython.core import ultratb
sys.excepthook = ultratb.FormattedTB(mode='Verbose',
color_scheme='Linux', call_pdb=1)

mode 关键字可以是“Verbose”或“Plain”,分别提供非常详细或正常的回溯。color_scheme 关键字可以是“NoColor”、“Linux”(默认)或“LightBG”。这些是可以在 IPython 中使用 --colors--xmode 设置的相同选项。

这将为你的任何程序提供详细的彩色回溯,并自动调用 pdb。

从 Python 或 IPython 提示符开始粘贴代码

IPython 足够智能,可以过滤掉输入提示,无论是普通的 Python 提示(>>>...)还是 IPython 提示(In [N]:...:)。因此,你可以从现有的交互式会话中复制和粘贴,而不用担心。

以下是对工作原理的“屏幕截图”,复制了标准 Python 教程中的一个示例

In [1]: >>> # Fibonacci series:

In [2]: ... # the sum of two elements defines the next

In [3]: ... a, b = 0, 1

In [4]: >>> while b < 10:
   ...:     ...     print(b)
   ...:     ...     a, b = b, a+b
   ...:
1
1
2
3
5
8

从 IPython 会话中粘贴同样有效

In [1]: In [5]: def f(x):
   ...:        ...:     "A simple function"
   ...:        ...:     return x**2
   ...:    ...:

In [2]: f(3)
Out[2]: 9

GUI 事件循环支持

IPython 非常适合与图形用户界面 (GUI) 工具包(如 wxPython、PyQt/PySide、PyGTK 和 Tk)进行交互式操作。这是通过在 IPython 等待输入时运行工具包的事件循环来实现的。

对于用户来说,启用 GUI 事件循环集成非常简单。只需使用 %gui 魔术,如下所示

%gui [GUINAME]

如果没有参数,%gui 将移除所有 GUI 支持。有效的 GUINAME 参数包括 wxqtqt5qt6gtk3 gtk4tk

因此,要以交互方式使用 wxPython 并创建一个正在运行的 wx.App 对象,请执行

%gui wx

您还可以使用 --gui 标志启动 IPython 并设置事件循环

$ ipython --gui=qt

有关 IPython 的 matplotlib 集成(和 matplotlib 模式)的信息,请参阅 本节

对于希望将其他事件循环与 IPython 集成的开发者,请参阅 与 GUI 事件循环集成

在 IPython 中使用集成事件循环运行时,GUI 应用程序不应启动自己的事件循环。这意味着既可以在 IPython 中使用又可以作为独立应用程序使用的应用程序需要有特殊代码来检测应用程序的运行方式。我们强烈建议使用 IPython 的支持来实现此目的。由于不同工具包之间的细节略有不同,因此我们建议您参考源目录 examples/IPython Kernel/gui/ 中的各种示例,这些示例演示了这些功能。

PyQt 和 PySide

当您使用 --gui=qt--matplotlib=qt 时,IPython 可以与 PyQt 或 PySide 配合使用。 qt 意味着“使用可用的最新版本”,并且它优先使用 PyQt 而不是 PySide。要请求特定版本,请使用 qt5qt6

如果指定,IPython 将尊重环境变量 QT_API。如果未指定 QT_API,并且您使用 ipython --matplotlib=qt 以 matplotlib 模式启动 IPython,那么 IPython 将询问 matplotlib 使用哪个 Qt 库。有关 QT_API 的更多详细信息,请参阅 matplotlib 文档。

使用 matplotlib 绘图

matplotlib 为 Python 提供高质量的 2D 和 3D 绘图。matplotlib 可以使用各种 GUI 工具包在屏幕上生成绘图,包括 Tk、PyGTK、PyQt6 和 wxPython。它还提供许多对科学计算有用的命令,所有这些命令的语法都与流行的 Matlab 程序兼容。

要使用 matplotlib 支持启动 IPython,请使用 --matplotlib 开关。如果 IPython 已经在运行,则可以运行 %matplotlib 魔术。如果未给出任何参数,IPython 将自动检测您选择的 matplotlib 后端。有关 matplotlib 后端的信息,请参阅 绘图

使用 IPython 进行交互式演示

IPython 附带了一个基本系统,用于分段交互式运行脚本,在向受众展示代码时很有用。注释中嵌入的几个标记(以便脚本仍然是有效的 Python 代码)将文件分成单独的块,并且可以一次运行一个块的演示,IPython 在执行之前打印(带语法高亮)该块,并在每个块之后返回到交互式提示符。在使用演示的命名空间的内容运行每个块后,将更新交互式命名空间。

这允许您显示一段代码,运行它,然后基于刚创建的变量执行交互式命令。一旦您想要继续,只需执行演示的下一个块。以下列表显示了将脚本划分为部分以作为演示执行所需的标记

# -*- coding: utf-8 -*-
"""A simple interactive demo to illustrate the use of IPython's Demo class.

Any python script can be run as a demo, but that does little more than showing
it on-screen, syntax-highlighted in one shot.  If you add a little simple
markup, you can stop at specified intervals and return to the ipython prompt,
resuming execution later.

This is a unicode test, åäö
"""

print('Hello, welcome to an interactive IPython demo.')
print('Executing this block should require confirmation before proceeding,')
print('unless auto_all has been set to true in the demo object')

# The mark below defines a block boundary, which is a point where IPython will
# stop execution and return to the interactive prompt.
# <demo> --- stop ---

x = 1
y = 2

# <demo> --- stop ---

# the mark below makes this block as silent
# <demo> silent

print('This is a silent block, which gets executed but not printed.')

# <demo> --- stop ---
# <demo> auto
print('This is an automatic block.')
print('It is executed without asking for confirmation, but printed.')
z = x+y

print('z=',x)

# <demo> --- stop ---
# This is just another normal block.
print('z is now:', z)

print('bye!')

为了将文件作为演示运行,您必须首先从中创建一个 Demo 对象。如果文件名为 myscript.py,则以下代码将创建一个演示

from IPython.lib.demo import Demo

mydemo = Demo('myscript.py')

这将创建 mydemo 对象,您可以通过不带任何参数简单地调用该对象来一次运行一个块。然后调用它来运行演示的每一步

mydemo()

可以重新启动 Demo 对象,您可以向前或向后跳过块,重新执行最后一个块,等等。请参阅 IPython.lib.demo 模块和 Demo 类以获取详细信息。

限制:这些演示仅限于相当简单的用途。特别是,您不能分解缩进代码(循环、if 语句、函数定义等)中的部分。支持这样的事情基本上需要跟踪 Python 解释器的内部执行状态,因此只允许顶级划分。如果您希望能够在程序中的任意点打开 IPython 实例,可以使用 IPython 的 嵌入功能