Як я можу відключити нову функцію історії в Python 3.4?


10

Після оновлення до Python 3.4 всі інтерактивні команди реєструються в ~/.python_history. Я не хочу, щоб Python створював або записував у цей файл.

Створення символьного посилання /dev/nullне працює, Python видаляє файл і відтворює його. Документація пропонує видалити sys.__interactivehook__, але це також видаляє табуляції завершення. Що потрібно зробити, щоб вимкнути запис цього файлу історії, але все-таки зберегти заповнення вкладки?

Додаткові дані:


Чи спробували ви заглушити його на корінь?
золотинки

@goldilocks Я не вважаю це прийнятним рішенням, і жодне з них не використовує chattr. Я шукаю єдиний (користувальницький) файл конфігурації або змінну середовища.
Лекенштейн

Гаразд, але ви вже знаєте, що немає такого прийнятного рішення, оскільки ви подивилися документацію.
золотинки

Насправді, chmodце рішення, запропоноване python devs у цьому звіті про помилки від декількох тижнів тому, хоча там також є деякі згадки ~/.inputrc(немає man readline, BTW, крім функції бібліотеки).
золотинки

@goldilocks Так, я збирався зв’язатись із цим звітом про помилку. Я не знаю, як використовувати, inputrcхоча і chmodне працює для мене, файл все одно змінюється (Arch Linux). info inputrcСторінка існує , але я, як правило, не задоволений читанням інформаційних сторінок, оскільки по них важко пересуватися.
Лекенштейн

Відповіді:


7

Станом на Python 3.6, ви можете використовувати readline.set_auto_history, щоб відключити це:

import readline
readline.set_auto_history(False)

Це добре для оболонки Python, але будьте обережні: він, здається, не працює в ipython.
z0r

Це повністю вимикає історію. Особисто мені добре, що історія зберігається в моєму сеансі перекладача, але я просто не хочу, щоб моя історія записувалася на диск і зберігалася протягом сеансів.
jamesdlin

Не працює. Це не зупиняє збереження файлу, а замість цього розбиває історію під час сеансу. У будь-якому випадку, Python мовчки повертає "функцію" при наступному запуску.
Boann

5

Це працює для мене.

Створення ~/.pythonrcфайлу:

import os
import atexit
import readline

readline_history_file = os.path.join(os.path.expanduser('~'), '.python_history')
try:
    readline.read_history_file(readline_history_file)
except IOError:
    pass

readline.set_history_length(0)
atexit.register(readline.write_history_file, readline_history_file)

Потім експортуйте його:

export PYTHONSTARTUP=~/.pythonrc

Здається, це дозволяє створити файл історії, а не вимикати його, якщо я не помиляюся? Якщо тільки set_history_lengthне робиться щось магічне? Заповнення вкладок виконується для функцій, а не історії.
Лекенштейн

@Lekensteyn: так, розмір історії дорівнює нулю, тому нічого не записується у файл історії. О, я хоч хочете зберегти команду між сеансами.
cuonglm

2
Це все ще призводить ~/.python_historyдо написання (перевіреного PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Я починаю вважати, що немає можливості відключити це, але продовжуйте заповнення вкладки без дублювання коду з /usr/lib/python3.4/site.py.
Лекенштейн

AFAIK, немає жодного способу реально його відключити.
cuonglm

3

Ще одне рішення ~ / .pythonrc:

import readline
readline.write_history_file = lambda *args: None

Я не знаю, чому цього більше не підтримують. Це просто і безпосередньо пригнічує запис файлу історії, а не повністю вимикати історію.
jamesdlin

Це було єдине виправлення, яке працювало на мене. Дякую.
Boann

1

Щоб Python не писав ~/.python_history, відключіть гачок, що активує цю функціональність:

import sys
# Disable history (...but also auto-completion :/ )
if hasattr(sys, '__interactivehook__'):
    del sys.__interactivehook__

Якщо ви хочете включити заповнення вкладки та відключити функцію історії, ви можете адаптувати site.enablerlcompleterкод. Напишіть наступний код ~/.pythonrcі встановіть export PYTHONSTARTUP=~/.pythonrcу свою оболонку, щоб увімкнути його.

import sys
def register_readline_completion():
    # rlcompleter must be loaded for Python-specific completion
    try: import readline, rlcompleter
    except ImportError: return
    # Enable tab-completion
    readline_doc = getattr(readline, '__doc__', '')
    if readline_doc is not None and 'libedit' in readline_doc:
        readline.parse_and_bind('bind ^I rl_complete')
    else:
        readline.parse_and_bind('tab: complete')
sys.__interactivehook__ = register_readline_completion

0

Поки це не виправлено якимось чином в самому Python, ви можете це зробити в системах UNIX:

rm ~/.python-history
mkdir ~/.python-history
sudo chattr +i ~/.python-history || sudo chflags simmutable ~/.python-history

Після цього ви будете отримувати

Помилка в atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] - це каталог

кожного разу, коли ви припиняєте оболонку пітона. Статус виходу все одно буде 0.

Зауважте, що якщо ви залишите його як файл, вам потрібно створити та зробити непорушним інший файл, ~/.python_history


0

Помістіть у файл наступне та встановіть PYTHONSTARTUPйого (або зателефонуйте до файлу sitecustomize.pyта зробіть його доступним із пункту PYTHONPATH)

import readline
import atexit
import sys

sys.__interactivehook__()
atexit.unregister(readline.write_history_file)

Таким чином, ви все одно матимете доступ до заповнення вкладки та попередньої історії, але введені команди не будуть додані до файлу історії.


Це, здається, не працює (Python 3.5.1 на Arch Linux), файл історії все ще пишеться при виході навіть через PYTHONSTARTUPсценарій справді виконується.
Лекенштейн

Я щойно тестував його на своєму Arch Linux vm, і він працює чудово: gist.github.com/berdario/640b3ab00b128fdf3338
berdario

0

Ось мій метод (який виявився в основному більш надійним і пітонічним варіантом методу бердаріо). Він забороняє писати .python_history, але не читати з нього, якщо він існує, або додавати нові рядки до історії поточного екземпляра. Я рекомендую зберегти його як site-packages/sitecustomize.py, тому що siteце модуль, який і записує, .python_historyі імпортує, sitecustomizeякщо він існує , хоча іменує його чимось іншим і вказує на нього PYTHONSTARTUPтакож.

import sys
oldhook = getattr(sys, '__interactivehook__', None)
if oldhook:
    def newhook():
        import readline, atexit
        oldhook()
        atexit.unregister(readline.write_history_file)
    sys.__interactivehook__ = newhook

оновлення: що я робив для 3.7, характерно для моєї системи, а не pep8:

import rlcompleter,readline as r,sys
def f():r.parse_and_bind('tab:complete');r.read_init_file()
sys.__interactivehook__=f

Пітон 3.7.3. Не працює. Історія все ще записується.
Boann

0

Моє поточне рішення (для достатньо останніх версій Python 3) запобігає використанню за замовчуванням ~ / .python_history, але залишає можливість явного запису історії до певного файлу (використовуючи readline.write_history_file (ім'я файлу) або readline.append_history_file (... )) у файлі PYTHONSTARTUP є наступне:

import readline
import time

readline.add_history("# " + time.asctime()) # prevent default use of ~/.python_history
readline.set_history_length(-1) # unlimited

Це приємна (для мене) побічна дія, що маркує будь-яку явно написану історію з часом запуску перекладача. Він працює через виправлення помилки 5845, яке можна побачити тут .

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.