Wie kann ich die neue Verlaufsfunktion in Python 3.4 deaktivieren?


10

Seit dem Upgrade auf Python 3.4 werden alle interaktiven Befehle protokolliert ~/.python_history. Ich möchte nicht, dass Python diese Datei erstellt oder in sie schreibt.

Das Erstellen eines Symlinks zu /dev/nullfunktioniert nicht. Python entfernt die Datei und erstellt sie neu. In der Dokumentation wird vorgeschlagen , das zu löschen sys.__interactivehook__, dies entfernt jedoch auch die Tab-Vervollständigung. Was sollte getan werden, um das Schreiben dieser Verlaufsdatei zu deaktivieren und gleichzeitig die Tab-Vervollständigung beizubehalten?

Zusätzliche Details:


Haben Sie versucht, es zu rooten?
Goldlöckchen

@goldilocks Ich halte das nicht für eine akzeptable Lösung und verwende sie auch nicht chattr. Ich suche eine einzelne (Benutzer-) Konfigurationsdatei oder Umgebungsvariable.
Lekensteyn

Okay, aber Sie wissen bereits, dass es keine so akzeptable Lösung gibt, da Sie sich die Dokumentation angesehen haben.
Goldlöckchen

In der Tat chmodist die Lösung von Python-Entwicklern in diesem Fehlerbericht von vor einigen Wochen vorgeschlagen, obwohl es auch einige Erwähnungen ~/.inputrcgibt (es gibt keine man readline, BTW, außer der Bibliotheksfunktion).
Goldlöckchen

@goldilocks Ja, ich wollte gerade auf diesen Fehlerbericht verlinken. Ich weiß jedoch nicht, wie ich es verwenden soll inputrcund chmodfunktioniert auch nicht für mich. Die Datei wird trotzdem geändert (Arch Linux). Es gibt eine info inputrcSeite, aber ich bin im Allgemeinen nicht so zufrieden mit dem Lesen von Infoseiten, da sie schwer zu navigieren sind.
Lekensteyn

Antworten:


7

Ab Python 3.6 können Sie readline.set_auto_history verwenden , um dies zu deaktivieren:

import readline
readline.set_auto_history(False)

Das ist gut für die Python-Shell, aber Vorsicht: Es scheint in ipython nicht zu funktionieren.
z0r

Dies deaktiviert die Geschichte vollständig. Persönlich kann ich den Verlauf in meiner Dolmetschersitzung gut aufbewahren, aber ich möchte einfach nicht, dass mein Verlauf auf die Festplatte geschrieben und über mehrere Sitzungen hinweg gespeichert wird.
Jamesdlin

Funktioniert nicht Dadurch wird das Speichern der Datei nicht gestoppt, sondern der Verlauf während der Sitzung wird unterbrochen. In jedem Fall schaltet Python die "Funktion" beim nächsten Ausführen stillschweigend wieder ein.
Boann

5

Das funktioniert bei mir.

Erstellen von ~/.pythonrcDatei:

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)

Dann exportieren Sie es:

export PYTHONSTARTUP=~/.pythonrc

Dies scheint das Schreiben einer Verlaufsdatei zu ermöglichen , anstatt sie zu deaktivieren , wenn ich mich nicht irre? Es sei set_history_lengthdenn, etwas Magisches? Das Ausfüllen der Registerkarten erfolgt für Funktionen, nicht für den Verlauf.
Lekensteyn

@Lekensteyn: Ja, dadurch wird die Verlaufsgröße gleich Null, sodass nichts in die Verlaufsdatei geschrieben wird. Oh, ich denke, Sie möchten den Befehl zwischen den Sitzungen beibehalten.
Cuonglm

2
Dies führt immer noch dazu ~/.python_history, dass geschrieben (verifiziert mit PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Ich fange an zu denken, dass es keine Möglichkeit gibt, dies zu deaktivieren, aber die Tab-Vervollständigung beizubehalten, ohne den Code von zu duplizieren /usr/lib/python3.4/site.py.
Lekensteyn

AFAIK, es gibt keine Möglichkeit, es wirklich zu deaktivieren.
Cuonglm

2

Eine andere ~ / .pythonrc-Lösung:

import readline
readline.write_history_file = lambda *args: None

Ich weiß nicht, warum dies nicht mehr positiv bewertet wird. Dies ist einfach und unterdrückt direkt das Schreiben der Verlaufsdatei, anstatt den Verlauf vollständig zu deaktivieren.
Jamesdlin

Dies war die einzige Lösung, die bei mir funktioniert hat. Vielen Dank.
Boann

1

Deaktivieren Sie den Hook , der diese Funktionalität aktiviert ~/.python_history, um zu verhindern, dass Python schreibt :

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

Wenn Sie die Tab-Vervollständigung aktivieren und die Verlaufsfunktion deaktivieren möchten, können Sie den site.enablerlcompleterCode anpassen . Schreiben Sie den folgenden Code in Ihre Shell ~/.pythonrcund legen export PYTHONSTARTUP=~/.pythonrcSie ihn fest, um ihn zu aktivieren.

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

Bis es in Python selbst auf irgendeine Weise behoben ist, können Sie dies auf UNIX-Systemen tun:

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

Danach wirst du bekommen

Fehler in atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] Ist ein Verzeichnis

Jedes Mal, wenn Sie eine Python-Shell beenden. Der Exit-Status bleibt bestehen 0.

Beachten Sie, dass Sie eine andere Datei erstellen und unveränderlich machen müssen, wenn Sie sie als Datei belassen. ~/.python_history


0

Fügen Sie Folgendes in eine Datei ein und stellen Sie PYTHONSTARTUPes ein (oder rufen Sie die Datei auf sitecustomize.pyund machen Sie sie über die Datei zugänglich PYTHONPATH).

import readline
import atexit
import sys

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

Auf diese Weise haben Sie weiterhin Zugriff auf die Tab-Vervollständigung und den vorherigen Verlauf, aber die von Ihnen eingegebenen Befehle werden nicht zur Verlaufsdatei hinzugefügt.


Dies scheint nicht zu funktionieren (Python 3.5.1 unter Arch Linux), die Verlaufsdatei wird beim Beenden noch geschrieben, obwohl das PYTHONSTARTUPSkript tatsächlich ausgeführt wird.
Lekensteyn

Ich habe es gerade auf meinem Arch Linux vm getestet und es funktioniert einwandfrei
berdario

0

Hier ist meine Methode (die sich im Grunde als zuverlässigere und pythonischere Version von Berdarios Methode herausstellte). Es deaktiviert nur das Schreiben .python_history, aber nicht das Lesen, wenn es vorhanden ist, oder das Anhängen neuer Zeilen an den Verlauf der aktuellen Instanz. Ich empfehle, es als zu speichern site-packages/sitecustomize.py, da sitees sich um das Modul handelt, in das sowohl geschrieben .python_historyals auch importiert wird, sitecustomizewenn es vorhanden ist , obwohl es auch PYTHONSTARTUPfunktioniert , wenn Sie es anders benennen und mit darauf zeigen .

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

Update: Was ich für 3.7 getan habe, spezifisch für mein System, nicht pep8:

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

Python 3.7.3. Funktioniert nicht. Verlauf noch protokolliert.
Boann

0

Meine aktuelle Lösung (für ausreichend aktuelle Versionen von Python 3) verhindert die Standardverwendung von ~ / .python_history, lässt jedoch die Möglichkeit, den Verlauf explizit in eine bestimmte Datei zu schreiben (mithilfe von readline.write_history_file (Dateiname) oder readline.append_history_file (... )) muss Folgendes in der PYTHONSTARTUP-Datei enthalten sein:

import readline
import time

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

Es hat den angenehmen (für mich) Nebeneffekt, dass jede explizit geschriebene Geschichte mit der Startzeit des Dolmetschers gekennzeichnet wird. Es funktioniert aufgrund des Fixes für Fehler 5845, der hier zu sehen ist .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.