如何在没有终端提示的情况下从 IPython 会话复制

How to Copy from IPython session without terminal prompts

我的工作流程经常涉及 cleaning/munging IPython shell 中的数据。自 IPython 5.0 版以来,这变得特别精彩,拥有所有伟大的 upgrades to the terminal interface。因此,假设我尝试整理一些非结构化数据:

In [11]: for i, (num, header, txt) in enumerate(data):
    ...:     header = [e.strip() for e in header.strip().split('\n')]
    ...:     header[4] = header[4].strip(',').split(',')
    ...:     data[i] = (num, header, txt)
    ...:

太棒了,效果很好!但是现在,我真的很想将它添加到我的编辑器中的脚本中。如果我从我的终端复制和粘贴,我会捕获左边的所有垃圾。我可以在编辑器中或多或少地轻松清理它,但如果我可以将代码直接从终端复制到我的剪贴板,而无需触摸鼠标,也无需抓取额外的东西,那就太好了。 IPython有这样的功能吗?

我不认为终端应用程序真的可以访问 copy/paste 缓冲区。你将不得不使用鼠标。如何操作取决于您使用的终端。大多数现代终端都有某种 "rectangular select" 或 "block select" 模式。

对于 Windows,矩形 select 是 cmd.exe 和 Powershell 的默认值。如果您使用的是 Cygwin 的 mintty,请按住 Alt,然后用鼠标按住 select 该区域。 PuTTY 也是如此。

在 Linux 上(我面前没有 - 对这些持保留态度),xterm 不支持它,Gnome 终端使用 Ctrl 作为修饰符,而 KDE 的 Konsole 使用 Ctrl+Alt.

对于 OS X 终端,互联网告诉我您在单击时使用

其他终端(和 GNU Screen)可能具有此功能,只是弄清楚如何激活它的问题。

您可以使用 %history 魔法从会话中提取有趣的部分。它们将在没有任何垃圾的情况下显示在终端中。

例子

In [1]: import numpy as np    
In [2]: a = np.random(10)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-83ce219ad17b> in <module>()
----> 1 a = np.random(10)

TypeError: 'module' object is not callable

In [3]: a = np.random.random(10)
In [4]: for i in a:
   ...:     print(i)
   ...:     
0.688626523886
[...]
0.341394850998

如果我想保存上面会话的一部分,我可以使用:

In [5]: %history 1 3-4

import numpy as np
a = np.random.random(10)
for i in a:
    print(i)

在上面的示例中,我使用 %history 1 3-4 到 assemble 所有我想保留的命令,并省略了我不需要的命令(第 2 行,有错误的那个)。现在您有了可以很好地复制的会话版本。

正在写入文件

您也可以使用 -f FILENAME 作为参数直接将其写入文件。

In [8]: %history 1 3-4 -f /tmp/foo.py

不过要小心,这会覆盖现有文件。 可以在 documentation of the %history magic.

中找到更多详细信息

在 shell 中,您可以先将 IPython 文件转换为常规 Python 文件 (.py),然后进行清理:

http://ipython.org/ipython-doc/3/notebook/nbconvert.html(参见 --to 脚本格式)

您也可以在笔记本编辑器中将文件下载为 Python 文件,并在此步骤后执行清理。

所以,我终于找到了一个很好的解决方案,它基本上正是我想要的:在 IPython 中使用 Vi 模式。在版本 5 上,这需要:

$ ipython --TerminalInteractiveShell.editing_mode=vi

现在我可以使用方便的类似 vi 的可视化模式并随心所欲地抽取!

这导致我的 .bash_profile/.bash_rc 中出现以下新别名:

alias vpython='ipython --TerminalInteractiveShell.editing_mode=vi'

save魔法命令[documentation]将你想要的输入行保存到一个文件; -a 选项用于 "append" 模式,以便将行添加到文件末尾而不是覆盖文件。我一直在用它。

以你为例:

%save -a myfile.py 11
# the '%' is not necessary
save -a myfile.py 11

然后你可以继续在 IPython 中编码。

当有另一个命令要写入同一文件时,您只需键入 save,然后使用向上箭头返回上次使用的 "save"(以便 -a 选项和文件名已经存在),只需编辑行号即可。

请注意,您可以提供多行来保存以及行范围:

save -a myfile.py 15 18 19-25