13. 交互式 Importing 编辑和历史记录替换

某些版本的 Python 解释器支持编辑当前 Importing 行和历史记录替换,类似于 Korn shell 和 GNU Bash shell 中的Function。这是使用GNU Readline库实现的,该库支持 Emacs 风格和 vi 风格的编辑。这个库有自己的文档,在这里我不会重复。但是,基本原理很容易解释。此处描述的交互式编辑和历史记录可以在解释器的 Unix 和 Cygwin 版本中可选使用。

本章没有*记录 Mark Hammond 的 PythonWin 软件包或随 Python 分发的基于 Tk 的环境 IDLE 的编辑Function。在 NT 上的 DOS 框内以及其他一些 DOS 和 Windows 风格下运行的命令行历史记录回忆是另一回事。

13.1. 行编辑

如果支持,则每当解释器打印主提示或辅助提示时,Importing 行编辑即处于活动状态。可以使用常规的 Emacs 控制字符来编辑当前行。其中最重要的是:C-A(Control-A)将光标移至行的开头,C-E 移至行的末尾,C-B 将其向左移一个位置,C-F 向右移。退格键删除光标左侧的字符,C-D 删除光标右侧的字符。 C-K 杀死(擦除)光标右侧的其余行,C-Y 拖动最后一个被杀死的字符串。 C 下划线撤消您所做的最后更改;可以重复进行累积效果。

13.2. 历史替代

历史替换的工作原理如下。发出的所有非空 Importing 行都保存在历史记录缓冲区中,并且在给出新提示时,您将位于该缓冲区底部的新行中。 C-P 在历史记录缓冲区中上移(后退)一行,C-N 下移一行。历史缓冲区中的任何行都可以编辑;提示前面会出现一个星号,以将行标记为已修改。按回车键会将当前行传递到解释器。 C-R 开始增量反向搜索; C-S 开始向前搜索。

13.3. 按键绑定

pass将命令放在名为~/.inputrc的初始化文件中,可以自定义 Readline 库的键绑定和其他一些参数。按键绑定具有以下形式

key-name: function-name

or

"string": function-name

和选项可以设置

set option-name value

For example:

# I prefer vi-style editing:
set editing-mode vi

# Edit using a single line:
set horizontal-scroll-mode On

# Rebind some keys:
Meta-h: backward-kill-word
"\C-u": universal-argument
"\C-x\C-r": re-read-init-file

请注意,Python 中 Tab 的默认绑定是插入 Tab 字符,而不是 Readline 的默认文件名完成Function。如果您坚持要求,可以pass以下方式覆盖

Tab: complete

在您的~/.inputrc中。 (当然,如果习惯于使用 Tab 来执行此操作,则很难键入缩进的连续行.)

可以选择自动完成变量和模块名称。要以解释器的交互模式启用它,请将以下内容添加到启动文件中:[1]

import rlcompleter, readline
readline.parse_and_bind('tab: complete')

这会将 Tab 键绑定到完成Function,因此,按两次 Tab 键将提示完成。它查看 Python 语句名称,当前的局部变量和可用的模块名称。对于诸如string.a的点分表达式,它将评估表达式直到最后的'.',然后根据结果对象的属性建议补全。请注意,如果具有getattr()方法的对象是表达式的一部分,则这可以执行应用程序定义的代码。

Function更强大的启动文件可能类似于以下示例。注意,一旦不再需要它们,它将删除它创建的名称。这样做是因为启动文件是在与交互式命令相同的名称空间中执行的,并且删除名称避免了在交互式环境中产生副作用。您可能会发现保留一些导入的模块很方便,例如os,这在大多数与解释器的会话中都是必需的。

# Add auto-completion and a stored history file of commands to your Python
# interactive interpreter. Requires Python 2.0+, readline. Autocomplete is
# bound to the Esc key by default (you can change it - see readline docs).
#
# Store the file in ~/.pystartup, and set an environment variable to point
# to it:  "export PYTHONSTARTUP=~/.pystartup" in bash.

import atexit
import os
import readline
import rlcompleter

historyPath = os.path.expanduser("~/.pyhistory")

def save_history(historyPath=historyPath):
    import readline
    readline.write_history_file(historyPath)

if os.path.exists(historyPath):
    readline.read_history_file(historyPath)

atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath

13.4. 交互式 Interpreter 的替代品

与早期版本的解释器相比,此Function是一大进步。但是,还剩下一些希望:如果在连续行上建议了适当的缩进,那就太好了(解析器知道接下来是否需要缩进标记)。完成机制可能使用解释器的符号表。检查(甚至建议)匹配的括号,引号等的命令也将很有用。

已经存在了相当长一段时间的一种替代的增强型交互式解释器是IPython,它具有选项卡补全,对象浏览和高级历史记录 Management 的Function。也可以对其进行完全自定义,并将其嵌入其他应用程序中。另一个类似的增强交互式环境是bpython

Footnotes

  • [1]
    • 启动交互式解释器时,Python 将执行 PYTHONSTARTUP环境变量标识的文件的内容。要甚至针对非交互模式自定义 Python,请参见定制模块