13. 交互式输入编辑和历史替换 — Python 文档
13. 交互式输入编辑和历史替换
某些版本的 Python 解释器支持编辑当前输入行和历史替换,类似于 Korn shell 和 GNU Bash shell 中的功能。 这是使用 GNU Readline 库实现的,该库支持 Emacs 风格和 vi 风格的编辑。 这个库有自己的文档,我不会在这里复制; 但是,基础知识很容易解释。 此处描述的交互式编辑和历史记录在解释器的 Unix 和 Cygwin 版本中是可选的。
本章 不 记录 Mark Hammond 的 PythonWin 包或基于 Tk 的环境 IDLE(随 Python 分发)的编辑功能。 在 NT 和其他一些 DOS 和 Windows 风格的 DOS 框内运行的命令行历史回忆是另一种野兽。
13.1. 行编辑
如果支持,每当解释器打印主要或次要提示时,输入行编辑都处于活动状态。 当前行可以使用传统的 Emacs 控制字符进行编辑。 其中最重要的是: CA (Control-A) 将光标移动到行首,CE 到行尾,CB 移动一个位置向左,CF 向右。 Backspace 删除光标左侧的字符,CD 删除其右侧的字符。 CK 删除(擦除)光标右侧的其余行,CY 拉回最后删除的字符串。 C-underscore 撤消您所做的最后一次更改; 它可以重复累积效果。
13.2. 历史替代
历史替换的工作原理如下。 发出的所有非空输入行都保存在历史缓冲区中,当出现新提示时,您将位于该缓冲区底部的新行上。 CP在历史缓冲区中向上(向后)移动一行,CN向下移动一行。 历史缓冲区中的任何行都可以编辑; 提示前会出现一个星号,将一行标记为已修改。 按 Return 键将当前行传递给解释器。 CR开始增量反向搜索; CS 开始向前搜索。
13.3. 键绑定
Readline 库的键绑定和一些其他参数可以通过将命令放置在名为 ~/.inputrc
的初始化文件中来自定义。 键绑定具有以下形式
key-name: function-name
或者
"string": function-name
和选项可以设置
set option-name value
例如:
# 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 的默认文件名补全函数。 如果你坚持,你可以通过放置来覆盖它
Tab: complete
在您的 ~/.inputrc
中。 (当然,如果您习惯于为此目的使用 Tab,这会使键入缩进的连续行变得更加困难。)
可以选择自动完成变量和模块名称。 要在解释器的交互模式下启用它,请将以下内容添加到您的启动文件中:1
import rlcompleter, readline
readline.parse_and_bind('tab: complete')
这将 Tab 键绑定到完成功能,因此按 Tab 键两次表示完成; 它查看 Python 语句名称、当前局部变量和可用模块名称。 对于诸如 string.a
之类的带点表达式,它将计算表达式直到最终的 '.'
,然后根据结果对象的属性建议补全。 请注意,如果具有 __getattr__()
方法的对象是表达式的一部分,则这可能会执行应用程序定义的代码。
功能更强大的启动文件可能类似于此示例。 请注意,这会删除不再需要的名称; 这样做是因为启动文件在与交互式命令相同的命名空间中执行,并且删除名称可避免在交互式环境中产生副作用。 您可能会发现保留一些导入的模块很方便,例如 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. 交互式解释器的替代品
与早期版本的解释器相比,此功能向前迈进了一大步; 然而,仍有一些愿望:如果在连续行上建议适当的缩进会很好(解析器知道接下来是否需要缩进标记)。 完成机制可能会使用解释器的符号表。 检查(甚至建议)匹配括号、引号等的命令也很有用。
IPython 是一种替代的增强交互式解释器,它已经存在了很长一段时间,它具有制表符补全、对象探索和高级历史管理功能。 它还可以完全定制并嵌入到其他应用程序中。 另一个类似的增强交互环境是bpython。
脚注
- 1
- 当您启动交互式解释器时,Python 将执行由 PYTHONSTARTUP 环境变量标识的文件的内容。 要在非交互模式下自定义 Python,请参阅 自定义模块 。