Làm cách nào để tắt tính năng lịch sử mới trong Python 3.4?


10

Kể từ khi nâng cấp lên Python 3.4, tất cả các lệnh tương tác được ghi lại ~/.python_history. Tôi không muốn Python tạo hoặc ghi vào tệp này.

Tạo một liên kết tượng trưng để /dev/nullkhông hoạt động, Python xóa tệp và tạo lại nó. Các tài liệu cho thấy để xóa sys.__interactivehook__, nhưng điều này cũng loại bỏ tab hoàn thành. Nên làm gì để vô hiệu hóa việc ghi tệp lịch sử này nhưng vẫn duy trì hoàn thành tab?

Chi tiết bổ sung:


Bạn đã thử chown nó để root?
goldilocks

@goldilocks Tôi không coi đó là một giải pháp chấp nhận được và cũng không sử dụng chattr. Tôi đang tìm kiếm một tập tin cấu hình (người dùng) hoặc biến môi trường.
Lekensteyn

Được rồi, nhưng bạn đã biết không có giải pháp chấp nhận được như vậy kể từ khi bạn xem tài liệu.
goldilocks

Trên thực tế, chmodlà giải pháp được đề xuất bởi các nhà phát triển python trong báo cáo lỗi này từ vài tuần trước, mặc dù cũng có một số đề cập đến ~/.inputrcđó (không có man readline, BTW, ngoại trừ chức năng thư viện).
goldilocks

@goldilocks Có, tôi sắp liên kết đến báo cáo lỗi đó. Tôi cũng không biết cách sử dụng inputrcchmodcũng không hiệu quả với tôi, dù sao thì tệp cũng được sửa đổi (Arch Linux). Có tồn tại một info inputrctrang, nhưng tôi thường không hài lòng với việc đọc các trang thông tin vì chúng khó điều hướng qua.
Lekensteyn

Câu trả lời:


7

Kể từ Python 3.6, bạn có thể sử dụng readline.set_auto_history để vô hiệu hóa điều này:

import readline
readline.set_auto_history(False)

Điều đó tốt cho shell Python, nhưng hãy cẩn thận: nó dường như không hoạt động trong ipython.
z0r

Điều này vô hiệu hóa hoàn toàn lịch sử. Cá nhân tôi vẫn ổn với lịch sử được lưu giữ trong phiên thông dịch của mình, nhưng tôi không muốn lịch sử của mình được ghi vào đĩa và được lưu giữ qua các phiên.
jamesdlin

Không hoạt động. Điều này không dừng tập tin đang được lưu, và thay vào đó nó phá vỡ lịch sử trong phiên. Trong mọi trường hợp, Python âm thầm bật lại "tính năng" vào lần tiếp theo bạn chạy nó.
Boann

5

Điều này làm việc cho tôi.

Tạo ~/.pythonrctập tin:

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)

Sau đó xuất nó:

export PYTHONSTARTUP=~/.pythonrc

Điều này dường như cho phép viết một tập tin lịch sử thay vì vô hiệu hóa nó nếu tôi không nhầm? Trừ khi set_history_lengthlàm điều gì đó kỳ diệu? Hoàn thành tab được thực hiện cho các chức năng, không phải lịch sử.
Lekensteyn

@Lekensteyn: có, nó làm cho kích thước lịch sử bằng 0 nên không có gì được ghi vào tệp lịch sử. Ồ, tôi mặc dù bạn muốn duy trì lệnh giữa các phiên.
cuonglm

2
Điều này vẫn gây ra ~/.python_historyđể được viết (xác minh với PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python). Tôi bắt đầu nghĩ rằng không có cách nào để vô hiệu hóa điều này, nhưng hãy tiếp tục hoàn thành tab mà không cần sao chép mã từ đó /usr/lib/python3.4/site.py.
Lekensteyn

AFAIK, không có cách nào để thực sự vô hiệu hóa nó.
cuonglm

2

Một giải pháp khác ~ / .pythonrc:

import readline
readline.write_history_file = lambda *args: None

Tôi không biết tại sao điều này không được nâng cao hơn nữa. Điều này là đơn giản và trực tiếp ngăn chặn việc viết tệp lịch sử thay vì vô hiệu hóa hoàn toàn lịch sử.
jamesdlin

Đây là sửa chữa duy nhất làm việc cho tôi. Cảm ơn.
Boann

1

Để ngăn Python viết ~/.python_history, hãy tắt hook kích hoạt chức năng này:

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

Nếu bạn muốn bật hoàn thành tab và tắt tính năng lịch sử, bạn có thể điều chỉnh site.enablerlcompletermã. Viết mã sau đây ~/.pythonrcvà đặt export PYTHONSTARTUP=~/.pythonrctrong trình bao của bạn để kích hoạt nó.

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

Cho đến khi nó được sửa theo một cách nào đó trong chính Python, bạn có thể làm điều này trên các hệ thống UNIX:

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

Sau đó bạn sẽ nhận được

Lỗi trong atexit._run_exitfuncs:

IsADirectoryError: [Errno 21] Là một thư mục

mỗi khi bạn chấm dứt một vỏ trăn. Tình trạng thoát vẫn sẽ được 0.

Lưu ý rằng nếu bạn để nó dưới dạng tệp, bạn cần tạo và tạo một tệp khác bất biến, ~/.python_history


0

Đặt phần sau vào một tệp và đặt PYTHONSTARTUPvào tệp đó (hoặc gọi tệp sitecustomize.pyvà làm cho nó có thể truy cập được từ PYTHONPATH)

import readline
import atexit
import sys

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

Bằng cách này, bạn sẽ vẫn có quyền truy cập vào hoàn thành tab và lịch sử trước đó, nhưng các lệnh bạn nhập sẽ không được thêm vào tệp lịch sử.


Điều này dường như không hoạt động (Python 3.5.1 trên Arch Linux), tệp lịch sử vẫn được ghi khi thoát ngay cả khi PYTHONSTARTUPtập lệnh thực sự được thực thi.
Lekensteyn

Tôi mới thử nghiệm nó trên Arch Linux vm của tôi và nó hoạt động tốt: gist.github.com/berdario/640b3ab00b128fdf3338
berdario 10/2/2016

0

Đây là phương pháp của tôi (hóa ra về cơ bản là một phiên bản đáng tin cậy và đáng sợ hơn của phương pháp berdario). Nó chỉ vô hiệu hóa việc ghi vào .python_history, nhưng không đọc từ nó nếu nó tồn tại hoặc nối thêm các dòng mới vào lịch sử của cá thể hiện tại. Tôi khuyên bạn nên lưu nó dưới dạng site-packages/sitecustomize.py, bởi vì sitemô-đun vừa ghi .python_historyvà nhập sitecustomizenếu nó tồn tại , mặc dù đặt tên cho nó là một cái gì đó khác và chỉ vào nó với PYTHONSTARTUPcác công việc quá.

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

cập nhật: những gì tôi đã làm cho 3.7, cụ thể cho hệ thống của tôi, không phải 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. Không làm việc. Lịch sử vẫn còn đăng nhập.
Boann

0

Giải pháp hiện tại của tôi (đối với các phiên bản đủ gần đây của Python 3) ngăn việc sử dụng mặc định ~ / .python_history nhưng để lại khả năng ghi rõ ràng lịch sử vào một tệp nhất định (sử dụng readline.write_history_file (tên tệp) hoặc readline.append_history_file (... )) là để có các mục sau trong tệp PYTHONSTARTUP của một người:

import readline
import time

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

Nó có hiệu ứng phụ dễ chịu (đối với tôi) ghi nhãn bất kỳ lịch sử được viết rõ ràng với thời gian khởi động của trình thông dịch. Nó hoạt động vì sửa lỗi 5845 có thể thấy ở đây .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.