GNU readline接口详解(16) – Python语言(必读进阶学习教程)(参考资料)
该readline
模块定义了许多函数来促进从 Python 解释器完成和读取/写入历史文件。该模块可以直接使用,也可以通过rlcompleter
模块使用,该模块支持在交互式提示下完成 Python 标识符。使用此模块进行的设置会影响解释器的交互式提示和内置input()
函数提供的提示的行为。
Readline 键绑定可以通过初始化文件配置,通常 .inputrc
在您的主目录中。请参阅GNU Readline 手册中的Readline Init File 以获取有关该文件的格式和允许的结构以及 Readline 库的一般功能的信息。
注意
底层的 Readline 库 API 可以由libedit
库而不是 GNU readline 来实现。在 macOS 上,该readline
模块检测运行时正在使用哪个库。
的配置文件libedit
与 GNU readline 的配置文件不同。如果您以编程方式加载配置字符串,您可以检查文本“libedit”readline.__doc__
以区分 GNU readline 和 libedit。
如果您在 macOS 上使用editline / libedit
readline 仿真,则位于您的主目录中的初始化文件名为 .editrc
. 例如,以下内容~/.editrc
将打开vi键绑定和 TAB 完成:
python:bind -v
python:bind ^I rl_complete
初始化文件
以下函数与 init 文件和用户配置有关:
readline.
stringparse_and_bind(
)
- 执行字符串参数中提供的初始化行。
rl_parse_and_bind()
这在底层库中调用 。
readline.
filenameread_init_file([
])
- 执行一个 readline 初始化文件。默认文件名是最后使用的文件名。
rl_read_init_file()
这在底层库中调用。
行缓冲区
以下函数对行缓冲区进行操作:
readline.
get_line_buffer()
- 返回行缓冲区的当前内容(
rl_line_buffer
在底层库中)。
readline.
stringinsert_text(
)
- 在光标位置将文本插入行缓冲区。
rl_insert_text()
这在底层库中调用 ,但忽略返回值。
readline.
redisplay()
- 更改屏幕上显示的内容以反映行缓冲区的当前内容。
rl_redisplay()
这在底层库中调用。
历史文件
以下函数对历史文件进行操作:
readline.
filenameread_history_file([
])
- 加载一个 readline 历史文件,并将其附加到历史列表中。默认文件名是
~/.history
.read_history()
这在底层库中调用 。
readline.
filenamewrite_history_file([
])
- 将历史列表保存到 readline 历史文件,覆盖任何现有文件。默认文件名是
~/.history
.write_history()
这在底层库中调用 。
readline.
nelementsappend_history_file(
filename[,
])
- 将历史记录的最后n 个元素项附加到文件中。默认文件名是
~/.history
. 该文件必须已经存在。append_history()
这在底层库中调用 。此函数仅在 Python 编译为支持它的库版本时才存在。3.5 版中的新功能。
readline.
get_history_length()
readline.
lengthset_history_length(
)
- 设置或返回要保存在历史文件中的所需行数。该函数通过调用底层库
write_history_file()
来使用该值截断历史文件。history_truncate_file()
负值意味着无限的历史文件大小。
历史列表
以下函数对全局历史列表进行操作:
readline.
clear_history()
- 清除当前历史。
clear_history()
这在底层库中调用。Python 函数仅在 Python 编译为支持它的库版本时才存在。
readline.
get_current_history_length()
- 返回当前历史记录中的项目数。(这与 不同
get_history_length()
,后者返回将写入历史文件的最大行数。)
readline.
indexget_history_item(
)
- 返回index处历史项的当前内容。项目索引是从一开始的。
history_get()
这在底层库中调用。
readline.
posremove_history_item(
)
- 从历史记录中删除由其位置指定的历史记录项。该位置是从零开始的。
remove_history()
这在底层库中调用。
readline.
posreplace_history_item(
,line)
- 将由其位置指定的历史项目替换为line。该位置是从零开始的。
replace_history_entry()
这在底层库中调用。
readline.
lineadd_history(
)
- 将行附加到历史缓冲区,就好像它是最后输入的行一样。
add_history()
这在底层库中调用。
readline.
enabledset_auto_history(
)
add_history()
通过 readline 读取输入时启用或禁用自动调用。enabled参数应该是一个布尔值,当为 true 时,启用自动历史记录,当为 false 时,禁用自动历史记录。3.6 版中的新功能。
CPython 实现细节:默认情况下启用自动历史记录,对此的更改不会在多个会话中持续存在。
启动钩子
readline.
functionset_startup_hook([
])
- 设置或移除
rl_startup_hook
底层库回调调用的函数。如果指定了function,它将被用作新的钩子函数;如果省略 orNone
,则删除任何已安装的功能。在 readline 打印第一个提示之前调用该钩子时不带任何参数。
readline.
functionset_pre_input_hook([
])
- 设置或移除
rl_pre_input_hook
底层库回调调用的函数。如果指定了function,它将被用作新的钩子函数;如果省略 orNone
,则删除任何已安装的功能。在打印第一个提示之后并且就在 readline 开始读取输入字符之前调用该钩子,不带任何参数。此函数仅在 Python 编译为支持它的库版本时才存在。
完成
以下功能与实现自定义单词完成功能有关。这通常由 Tab 键操作,并且可以建议并自动完成正在键入的单词。默认情况下,Readline 设置为用于rlcompleter
完成交互式解释器的 Python 标识符。如果readline
模块要与自定义完成符一起使用,则应设置一组不同的单词分隔符。
readline.
functionset_completer([
])
- 设置或删除完成函数。如果指定了function,它将作为新的完成函数;如果省略 or
None
,则删除已安装的任何完成函数。完成函数被称为 , , , , …中的状态,直到它返回一个非字符串值。它应该返回以text开头的下一个可能的完成。function(text, state)
0
1
2
已安装的完成函数由传递给底层库的entry_func回调调用。文本字符串来自 底层库回调的
rl_completion_matches()
第一个参数。rl_attempted_completion_function
readline.
get_completer()
- 获取完成函数,或者
None
如果没有设置完成函数。
readline.
get_completion_type()
- 获取正在尝试的完成类型。这会将
rl_completion_type
底层库中的变量作为整数返回。
readline.
get_begidx()
readline.
get_endidx()
- 获取完成范围的开始或结束索引。这些索引是传递给底层库回调的开始和结束参数 。
rl_attempted_completion_function
readline.
set_completer_delims(string)
readline.
get_completer_delims()
- 设置或获取用于完成的单词分隔符。这些决定了要考虑完成的单词的开头(完成范围)。这些函数访问
rl_completer_word_break_characters
底层库中的变量。
readline.
functionset_completion_display_matches_hook([
])
- 设置或移除完成显示功能。如果指定了function,它将作为新的完成显示函数;如果省略 or
None
,则删除任何已安装的完成显示功能。这会设置或清除rl_completion_display_matches_hook
底层库中的回调。每次需要显示匹配项时,都会调用完成显示函数 。function(substitution, [matches], longest_match_length)
示例
下面的例子演示了如何使用readline
模块的历史读写功能来自动加载和保存一个以.python_history
用户主目录命名的历史文件。下面的代码通常会在用户的交互会话期间自动执行PYTHONSTARTUP
文件。
import atexit
import os
import readline
histfile = os.path.join(os.path.expanduser("~"), ".python_history")
try:
readline.read_history_file(histfile)
# default history len is -1 (infinite), which may grow unruly
readline.set_history_length(1000)
except FileNotFoundError:
pass
atexit.register(readline.write_history_file, histfile)
当Python以交互模式运行时,实际上会自动运行此代码 (请参阅Readline配置)。
以下示例实现了相同的目标,但仅通过附加新历史记录来支持并发交互式会话。
import atexit
import os
import readline
histfile = os.path.join(os.path.expanduser("~"), ".python_history")
try:
readline.read_history_file(histfile)
h_len = readline.get_current_history_length()
except FileNotFoundError:
open(histfile, 'wb').close()
h_len = 0
def save(prev_h_len, histfile):
new_h_len = readline.get_current_history_length()
readline.set_history_length(1000)
readline.append_history_file(new_h_len - prev_h_len, histfile)
atexit.register(save, h_len, histfile)
以下示例扩展了code.InteractiveConsole
类以支持历史记录保存/恢复。
import atexit
import code
import os
import readline
class HistoryConsole(code.InteractiveConsole):
def __init__(self, locals=None, filename="<console>", histfile=os.path.expanduser("~/.console-history")):
code.InteractiveConsole.__init__(self, locals, filename)
self.init_history(histfile)
def init_history(self, histfile):
readline.parse_and_bind("tab: complete")
if hasattr(readline, "read_history_file"):
try:
readline.read_history_file(histfile)
except FileNotFoundError:
pass
atexit.register(self.save_history, histfile)
def save_history(self, histfile):
readline.set_history_length(1000)
readline.write_history_file(histfile)