Постоянная история командной строки Python

Я хотел бы иметь возможность "стрелки вверх" к командам, которые я вводил в предыдущем интерпретаторе Python. Я нашел модуль readline, который предлагает такие функции, как: read_history_file, write_history_file и set_startup_hook. Я недостаточно разбираюсь в практике, но, может, кто-то может помочь? Мои мысли о решении:

(1) Измените .login PYTHONSTARTUP, чтобы запустить python script. (2) В этом файле python script сделайте что-то вроде:

def command_history_hook():
    import readline
    readline.read_history_file('.python_history')
command_history_hook()

(3) Всякий раз, когда переводчик завершает работу, напишите историю в файл. Я думаю, лучший способ сделать это - определить функцию в вашем запуске script и выйти с помощью этой функции:

def ex():
    import readline
    readline.write_history_file('.python_history')
    exit()

Это очень раздражает, когда нужно выходить с помощью круглых скобок: ex(). Есть ли какой-нибудь питон-сахар, который позволил бы ex (без парнов) запустить функцию ex?

Есть ли лучший способ заставить файл истории писать каждый раз? Заранее благодарим за все решения/предложения.

Кроме того, я вижу два архитектурных варианта. Один из вариантов - иметь единую историю команд. Преимущество - это простота (альтернатива, которая следует за пометом в ваш домашний каталог с большим количеством файлов.) Недостаток заключается в том, что интерпретаторы, которые вы запускаете в отдельных терминалах, будут заполняться друг с другом историями команд, и они будут перезаписывать одну другую историю. (это нормально для меня, так как я обычно заинтересован в том, чтобы закрыть интерпретатор и снова открыть его для перезагрузки модулей, и в этом случае команды интерпретатора будут записаны в файл.) Одно из возможных решений для поддержки отдельных файлов истории на каждый терминал это написать переменную среды для каждого создаваемого нового терминала:

def random_key()
    ''.join([choice(string.uppercase + string.digits) for i in range(16)])

def command_history_hook():
    import readline
    key = get_env_variable('command_history_key')
    if key:
        readline.read_history_file('.python_history_{0}'.format(key))
    else:
        set_env_variable('command_history_key', random_key())

def ex():
    import readline
    key = get_env_variable('command_history_key')
    if not key:
        set_env_variable('command_history_key', random_key())
    readline.write_history_file('.python_history_{0}'.format(key))
    exit()

Уменьшая длину случайного ключа от 16 до 1, вы можете уменьшить количество файлов, засоряющих ваши каталоги до 36, за счет возможной (2.8% вероятности) перекрытия.

Ответы

Ответ 1

Я думаю, что предложения в документации на Python в значительной степени охватывают то, что вы хотите. Посмотрите пример файла pystartup в конец раздела 13.3:

или на этой странице:

Но для интерактивной оболочки, которая предоставляет все это и многое другое, взгляните на использование IPython:

Ответ 2

Попробуйте использовать IPython в качестве оболочки python. У него уже есть все, о чем вы просите. У них есть пакеты для самых популярных дистрибутивов, поэтому установка должна быть очень простой.

Ответ 4

Используйте PIP для установки пакета pyreadline:

pip install pyreadline

Ответ 5

Если вы хотите использовать интерактивную замену истории без всех файлов, все, что вам нужно сделать, это импортировать readline:

import readline

И затем вы можете использовать клавиши вверх/вниз для навигации по прошлым командам. То же самое для 2 или 3.

Мне это не было ясно из документов, но, возможно, я пропустил это.