Bagaimana saya bisa menonaktifkan fitur histori baru di Python 3.4?


10

Sejak memutakhirkan ke Python 3.4, semua perintah interaktif dicatat ~/.python_history. Saya tidak ingin Python membuat atau menulis ke file ini.

Membuat symlink /dev/nulltidak berfungsi, Python menghapus file dan membuatnya kembali. The dokumentasi menyarankan untuk menghapus sys.__interactivehook__, tetapi ini juga menghilangkan tab-selesai. Apa yang harus dilakukan untuk menonaktifkan penulisan file riwayat ini tetapi masih mempertahankan penyelesaian tab?

Detil tambahan:


Sudahkah Anda mencoba mengunyahnya ke root?
goldilocks

@goldilocks Saya tidak menganggap itu solusi yang dapat diterima, dan tidak ada yang menggunakan chattr. Saya mencari satu file konfigurasi (pengguna) atau variabel lingkungan.
Lekensteyn

Oke, tetapi Anda sudah tahu tidak ada solusi yang dapat diterima karena Anda telah melihat dokumentasi.
goldilocks

Bahkan, chmodadalah solusi yang disarankan oleh python devs dalam laporan bug ini dari beberapa minggu yang lalu, meskipun ada juga beberapa yang menyebutkan ~/.inputrcada (tidak ada man readline, BTW, kecuali untuk fungsi perpustakaan).
goldilocks

@goldilocks Ya, saya akan menautkan ke laporan bug itu. Saya tidak tahu bagaimana cara menggunakan inputrcdan chmodtidak bekerja untuk saya juga, file akan tetap dimodifikasi (Arch Linux). Ada info inputrchalaman, tetapi saya biasanya tidak begitu senang membaca halaman info karena sulit untuk dijelajahi.
Lekensteyn

Jawaban:


7

Pada Python 3.6, Anda dapat menggunakan readline.set_auto_history untuk menonaktifkan ini:

import readline
readline.set_auto_history(False)

Itu bagus untuk shell Python, tetapi berhati-hatilah: sepertinya tidak bekerja di ipython.
z0r

Ini sepenuhnya menonaktifkan riwayat. Secara pribadi saya baik-baik saja dengan sejarah disimpan dalam sesi juru bahasa saya, tetapi saya hanya tidak ingin riwayat saya ditulis ke disk dan disimpan di seluruh sesi.
jamesdlin

Tidak bekerja Ini tidak menghentikan file yang disimpan, dan sebagai gantinya itu merusak sejarah selama sesi. Bagaimanapun, Python secara diam-diam mengembalikan "fitur" pada saat Anda menjalankannya.
Boann

5

Ini bekerja untuk saya.

Membuat ~/.pythonrcfile:

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)

Kemudian ekspor:

export PYTHONSTARTUP=~/.pythonrc

Ini sepertinya mengaktifkan penulisan file histori alih-alih menonaktifkannya jika saya tidak salah? Kecuali set_history_lengthmelakukan sesuatu yang ajaib? Penyelesaian tab dilakukan untuk fungsi, bukan riwayat.
Lekensteyn

@Lekensteyn: ya, itu membuat ukuran riwayat sama dengan nol sehingga tidak ada yang ditulis ke file riwayat. Oh, saya pikir Anda ingin mempertahankan perintah di antara sesi.
cuonglm

2
Ini masih menyebabkan ~/.python_historyditulis (diverifikasi dengan PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Saya mulai berpikir bahwa tidak ada cara untuk menonaktifkan ini, tetapi tetap lakukan penyelesaian tab tanpa menduplikasi kode /usr/lib/python3.4/site.py.
Lekensteyn

AFAIK, tidak ada cara untuk benar-benar menonaktifkannya.
cuonglm

2

Solusi ~ / .pythonrc lainnya:

import readline
readline.write_history_file = lambda *args: None

Saya tidak tahu mengapa ini tidak terunggulkan lagi. Ini sederhana dan secara langsung menekan penulisan file histori alih-alih menonaktifkan histori sepenuhnya.
jamesdlin

Ini adalah satu-satunya perbaikan yang berhasil untuk saya. Terima kasih.
Boann

1

Untuk mencegah Python dari menulis ~/.python_history, nonaktifkan kait yang mengaktifkan fungsi ini:

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

Jika Anda ingin mengaktifkan penyelesaian tab dan menonaktifkan fitur histori, Anda dapat mengadaptasi site.enablerlcompleterkode. Tulis kode berikut ke ~/.pythonrcdan atur export PYTHONSTARTUP=~/.pythonrcdi shell Anda untuk mengaktifkannya.

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

Sampai diperbaiki dengan cara tertentu di Python, Anda dapat melakukan ini pada sistem UNIX:

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

Setelah itu Anda akan mendapatkan

Kesalahan pada atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] Adalah direktori

setiap kali Anda menghentikan shell python. Status keluar masih akan 0.

Perhatikan bahwa jika Anda membiarkannya sebagai file, Anda perlu membuat dan membuat file lain yang tidak dapat diubah, ~/.python_history


0

Masukkan berikut ini dalam file dan atur PYTHONSTARTUPuntuk itu (atau panggil file sitecustomize.pydan buat itu dapat diakses dari PYTHONPATH)

import readline
import atexit
import sys

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

Dengan cara ini Anda masih memiliki akses ke penyelesaian tab dan riwayat sebelumnya, tetapi perintah yang Anda masukkan tidak akan ditambahkan ke file riwayat.


Ini sepertinya tidak berfungsi (Python 3.5.1 di Arch Linux), file histori masih tertulis saat keluar bahkan melalui PYTHONSTARTUPskrip memang dieksekusi.
Lekensteyn

Saya baru saja mengujinya di Arch Linux vm saya, dan berfungsi dengan baik: gist.github.com/berdario/640b3ab00b128fdf3338
berdario

0

Inilah metode saya (yang pada dasarnya merupakan versi metode berdario yang lebih andal dan pythonic). Ini hanya menonaktifkan penulisan .python_history, tetapi tidak membacanya jika ada, atau menambahkan baris baru ke riwayat instance saat ini. Saya sarankan menyimpannya sebagai site-packages/sitecustomize.py, karena siteadalah modul yang menulis .python_historydan mengimpor sitecustomizejika ada , meskipun menamainya sesuatu yang lain dan menunjuknya dengan PYTHONSTARTUPkarya juga.

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

pembaruan: apa yang saya lakukan untuk 3.7, khusus untuk sistem saya, bukan 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. Tidak bekerja Sejarah masih dicatat.
Boann

0

Solusi saya saat ini (untuk versi Python 3 yang cukup baru) mencegah penggunaan default ~ / .python_history tetapi meninggalkan kemungkinan penulisan sejarah secara eksplisit ke file yang diberikan (menggunakan readline.write_history_file (nama file) atau readline.append_history_file (... )) harus memiliki yang berikut dalam file PYTHONSTARTUP seseorang:

import readline
import time

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

Ini memiliki efek samping yang menyenangkan (bagi saya) memberi label riwayat tertulis secara eksplisit dengan waktu startup juru bahasa. Ini bekerja karena perbaikan untuk bug 5845 yang dapat dilihat di sini .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.