6.7. readline —— GNU readline接口

readline模块定义了许多函数,以便于从Python解释器完成和读取/写入历史文件。此模块可以直接使用,也可以通过rlcompleter模块使用,该模块支持在交互式提示符处完成Python标识符。使用此模块进行的设置会影响解释器的交互式提示和由内置input()函数提供的提示的行为。

注意

底层的Readline库API可以通过libedit库而不是GNU readline来实现。在MacOS X上,readline模块检测在运行时使用哪个库。

libedit的配置文件与GNU readline的配置文件不同。如果以编程方式加载配置字符串,您可以检查readline.__doc__中的文本“libedit”,以区分GNU readline和libedit。

Readline键绑定可以通过初始化文件配置,通常为主目录中的.inputrc有关该文件的格式和允许的结构以及一般的Readline库的功能的信息,请参阅GNU Readline手册中的Readline Init File

6.7.1.Init文件

以下函数与init文件和用户配置相关:

readline.parse_and_bind(string)

执行string参数中提供的init行。这会调用底层库中的rl_parse_and_bind()

readline.read_init_file([filename])

执行readline初始化文件。默认文件名是所使用的最后一个文件名。这会调用底层库中的rl_read_init_file()

6.7.2.行缓冲

以下功能对行缓冲区进行操作:

readline.get_line_buffer()

返回行缓冲区的当前内容(rl_line_buffer在底层库中)。

readline.insert_text(string)

在光标位置的行缓冲区中插入文本。这会调用底层库中的rl_insert_text(),但忽略返回值。

readline.redisplay()

更改屏幕上显示的内容以反映行缓冲区的当前内容。这会调用底层库中的rl_redisplay()

6.7.3.历史记录文件

以下功能操作历史文件:

readline.read_history_file([filename])

加载阅读历史记录文件,并将其附加到历史记录列表。默认文件名为~/.history这会调用底层库中的read_history()

readline.write_history_file([filename])

将历史记录列表保存到阅读历史记录文件,覆盖任何现有文件。默认文件名为~/.history这会调用底层库中的write_history()

readline.append_history_file(nelements[, filename])

将最后的nelements项目追加到文件中。默认文件名为~/.history文件必须已存在。这会在底层库中调用append_history()此函数仅在Python是为支持它的库的版本编译时才存在。

版本3.5中的新功能。

readline.get_history_length()
readline.set_history_length(length)

设置或返回要保存在历史记录文件中的所需行数。通过调用底层库中的history_truncate_file()write_history_file()函数使用此值截断历史记录文件。负值意味着无限的历史文件大小。

6.7.4.历史列表

以下功能对全局历史列表进行操作:

readline.clear_history()

清除当前历史记录。这在底层库中调用clear_history()如果Python是为支持它的库的版本编译的,Python函数才存在。

readline.get_current_history_length()

返回当前在历史记录中的项目数。(这不同于get_history_length(),它返回将写入历史文件的最大行数。)

readline.get_history_item(index)

返回索引的历史记录项目的当前内容。项目索引是从1开始的。这会调用底层库中的history_get()

readline.remove_history_item(pos)

从历史记录中删除其位置指定的历史记录项。位置是零为基础。这会在底层库中调用remove_history()

readline.replace_history_item(pos, line)

替换其位置指定的历史记录项。位置是零为基础。这会调用底层库中的replace_history_entry()

readline.add_history(line)

附加到历史记录缓冲区,就好像它是最后一行键入的。这会调用底层库中的add_history()

6.7.5.启动挂接

readline.set_startup_hook([function])

设置或删除由底层库的rl_startup_hook回调调用的函数。如果指定function,它将被用作新的钩子函数;如果省略或None,则已安装的任何功能都将被删除。在readline打印第一个提示之前,不使用参数来调用钩子。

readline.set_pre_input_hook([function])

设置或删除由底层库的rl_pre_input_hook回调调用的函数。如果指定function,它将被用作新的钩子函数;如果省略或None,则已安装的任何功能都将被删除。在第一个提示被打印后并且readline开始读取输入字符之前,没有参数的钩子被调用。此函数仅在Python是为支持它的库的版本编译时才存在。

6.7.6.完成

以下功能涉及实现自定义词语完成功能。这通常由Tab键操作,并且可以建议并自动完成键入的单词。默认情况下,Readline设置为由rlcompleter使用以完成交互式解释器的Python标识符。如果readline模块要与自定义完成程序一起使用,则应设置一组不同的字分隔符。

readline.set_completer([function])

设置或删除完成器功能。如果指定函数,它将用作新的完成函数;如果省略或None,则已删除已安装的任何完成器函数。The completer function is called as function(text, state), for state in 0, 1, 2, ..., until it returns a non-string value. 它应该返回从文本开始的下一个可能的完成。

安装的completionter函数由传递给底层库中的rl_completion_matches()entry_func回调调用。文本字符串来自基础库的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回调的startend参数。

readline.set_completer_delims(string)
readline.get_completer_delims()

设置或获取完成的单词分隔符。这些决定了要考虑完成的字的开始(完成范围)。这些函数访问底层库中的rl_completer_word_break_characters变量​​。

readline.set_completion_display_matches_hook([function])

设置或删除完成显示功能。如果指定函数,它将用作新的完成显示函数;如果省略或None,已安装的任何完成显示功能已删除。这会设置或清除底层库中的rl_completion_display_matches_hook回调。每次匹配需要时,完成显示功能称为功能(替换, [matches], longest_match_length)显示。

6.7.7.示例

以下示例演示如何使用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在interactive mode中运行时,该代码实际上自动运行(参见Readline configuration)。

以下示例实现了相同的目标,但是通过仅附加新历史记录来支持并发交互式会话。

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_history_length()
except FileNotFoundError:
    open(histfile, 'wb').close()
    h_len = 0

def save(prev_h_len, histfile):
    new_h_len = readline.get_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)