Документация Python неофициальный перевод
Содержание страницы

6.7. readline – интерфейс GNU readlinereadline – GNU readline interface


Модуль readline определяет ряд функций для упрощения дополнения и чтения/записи файлов истории из интерпретатора Python. Этот модуль можно использовать напрямую или через модуль rlcompleter, который поддерживает дополнение идентификаторов Python в интерактивной строке. Настройки, сделанные с помощью этого модуля, влияют на поведение как интерактивной строки интерпретатора, так и строк, предлагаемых встроенной функцией input().

Примечание

Базовый API библиотеки Readline может быть реализован библиотекой libedit вместо GNU readline. На MacOS X модуль readline определяет, какая библиотека используется во время выполнения.

Конфигурационный файл для libedit отличается от файла GNU readline. Если строки конфигурации загружаются программно, можно проверить наличие текста «libedit» в readline.__doc__, чтобы отличить GNU readline от libedit.

Привязки клавиш Readline можно настроить через файл инициализации, обычно .inputrc в вашем домашнем каталоге. Смотрите Файл инициализации Readline в руководстве GNU Readline для получения информации о формате и допустимых конструкциях этого файла, а также о возможностях библиотеки Readline в целом.

6.7.1. Файл инициализацииInit file

Следующие функции относятся к файлу инициализации и пользовательской конфигурации:

readline.parse_and_bind(string)

Выполняет строку инициализации, переданную в аргументе string. Это вызывает rl_parse_and_bind() в базовой библиотеке.

readline.read_init_file([filename])

Выполняет файл инициализации readline. По умолчанию используется имя последнего использованного файла. Вызывает rl_read_init_file() в базовой библиотеке.

6.7.2. Буфер строкиLine buffer

Следующие функции работают с буфером строки:

readline.get_line_buffer()

Возвращает текущее содержимое буфера строки (rl_line_buffer в базовой библиотеке).

readline.insert_text(string)

Вставляет текст в буфер строки в позиции курсора. Это вызывает rl_insert_text() в базовой библиотеке, но игнорирует возвращаемое значение.

readline.redisplay()

Изменяет отображаемое на экране, чтобы отразить текущее содержимое буфера строки. Это вызывает rl_redisplay() в базовой библиотеке.

6.7.3. Файл историиHistory file

Следующие функции работают с файлом истории:

readline.read_history_file([filename])

Загружает файл истории readline и добавляет его в список истории. По умолчанию используется имя файла ~/.history. Вызывает read_history() в базовой библиотеке.

readline.write_history_file([filename])

Сохраняет список истории в файл истории readline, перезаписывая любой существующий файл. По умолчанию используется имя файла ~/.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)

Устанавливает или возвращает нужное количество строк для сохранения в файле истории. Функция write_history_file() использует это значение для усечения файла истории, вызывая history_truncate_file() в нижележащей библиотеке. Отрицательные значения означают неограниченный размер файла истории.

6.7.4. Список историиHistory list

Следующие функции работают с глобальным списком истории:

readline.clear_history()

Очищает текущую историю. Вызывает clear_history() в нижележащей библиотеке. Функция Python существует только если Python был скомпилирован для версии библиотеки, которая её поддерживает.

readline.get_current_history_length()

Возвращает количество элементов, находящихся в истории. (Отличается от get_history_length(), которая возвращает максимальное количество строк, которое будет записано в файл истории.)

readline.get_history_item(index)

Возвращает текущее содержимое элемента истории по index. Индекс элемента начинается с 1. Вызывает history_get() в нижележащей библиотеке.

readline.remove_history_item(pos)

Удаляет элемент истории, заданный по его позиции, из истории. Позиция начинается с 0. Вызывает remove_history() в нижележащей библиотеке.

readline.replace_history_item(pos, line)

Заменяет элемент истории, заданный по его позиции, на line. Позиция начинается с 0. Вызывает replace_history_entry() в нижележащей библиотеке.

readline.add_history(line)

Добавляет line в буфер истории, как если бы это была последняя введённая строка. Вызывает add_history() в нижележащей библиотеке.

6.7.5. Хуки запускаStartup hooks

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. ДополнениеCompletion

Следующие функции относятся к реализации пользовательской функции завершения слов. Обычно она вызывается клавишей Tab и может предлагать и автоматически завершать вводимое слово. По умолчанию Readline настроен для использования rlcompleter для завершения идентификаторов Python в интерактивном интерпретаторе. Если модуль readline должен использоваться с пользовательским комплитером, следует задать другой набор разделителей слов.

readline.set_completer([function])

Установить или удалить функцию дополнения. Если указана function, она будет использоваться как новая функция дополнения; если опущена или None, любая установленная ранее функция дополнения удаляется. Функция дополнения вызывается как function(text, state) для state в 0, 1, 2, … пока не вернет нестроковое значение. Она должна возвращать следующее возможное дополнение, начинающееся с text.

Установленная функция дополнения вызывается колбэком entry_func, переданным в rl_completion_matches() в нижележащей библиотеке. Строка text берется из первого параметра колбэка rl_attempted_completion_function нижележащей библиотеки.

readline.get_completer()

Возвращает функцию дополнения или None, если функция дополнения не была установлена.

readline.get_completion_type()

Возвращает тип выполняемого дополнения. Возвращает переменную rl_completion_type из нижележащей библиотеки в виде целого числа.

readline.get_begidx()
readline.get_endidx()

Получить начальный или конечный индекс области завершения. Эти индексы – аргументы start и end, передаваемые в колбэк rl_attempted_completion_function нижележащей библиотеки.

readline.set_completer_delims(string)
readline.get_completer_delims()

Устанавливает или возвращает разделители слов для дополнения. Они определяют начало слова, для которого рассматривается дополнение (область дополнения). Эти функции обращаются к переменной rl_completer_word_break_characters в нижележащей библиотеке.

readline.set_completion_display_matches_hook([function])

Устанавливает или удаляет функцию отображения дополнений. Если указана function, она будет использоваться как новая функция отображения дополнений; если опущена или None, любая установленная ранее функция отображения дополнений удаляется. Эта функция устанавливает или очищает колбэк rl_completion_display_matches_hook в нижележащей библиотеке. Функция отображения дополнений вызывается как function(substitution, [matches], longest_match_length) каждый раз, когда нужно отобразить совпадения.

6.7.7. ПримерExample

Следующий пример демонстрирует, как использовать функции чтения и записи истории модуля 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)
    # длина истории по умолчанию равна -1 (бесконечность), что может привести к неконтролируемому росту
    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_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)