如何禁用Python 3.4中的新历史记录功能?


10

自从升级到Python 3.4之后,所有交互式命令都记录到~/.python_history。我不希望Python创建或写入此文件。

创建到的符号链接/dev/null无效,Python会删除该文件并重新创建它。该文档建议删除sys.__interactivehook__,但这也会删除制表符补全。如何禁用该历史记录文件,但仍保留制表符补全功能?

额外细节:


您是否尝试过将其扎根?
goldilocks 2014年

@goldilocks我认为这不是可接受的解决方案,也没有使用chattr。我正在寻找一个(用户)配置文件或环境变量。
Lekensteyn 2014年

好的,但是您已经了解了这样的解决方案,因为您已经阅读了文档。
goldilocks 2014年

实际上,这chmod是python开发人员在几周前在此bug报告中建议的解决方案,尽管那里也有提及~/.inputrc(没有man readline,BTW,除了库函数)。
goldilocks 2014年

@goldilocks是的,我正要链接到该错误报告。我不知道如何使用,inputrcchmod对我也不起作用,该文件无论如何都会被修改(Arch Linux)。有一个info inputrc页面,但是我通常不喜欢阅读信息页面,因为它们很难导航。
Lekensteyn 2014年

Answers:


7

从Python 3.6开始,您可以使用readline.set_auto_history禁用此功能:

import readline
readline.set_auto_history(False)

这对Python shell很有好处,但请注意:它似乎在ipython中不起作用。
z0r19年

这将完全禁用历史记录。就个人而言,我的历史记录可以保存在解释器会话中,但我只是不希望将历史记录写入磁盘并跨会话保存。
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

@Lekensteyn:是的,它使历史记录大小等于零,因此没有任何内容写入历史记录文件。哦,尽管您想保留会话之间的命令。
cuonglm 2014年

2
这仍然会导致~/.python_history被写入(已通过验证PYTHONSTARTUP=$HOME/.pythonrc strace -e file,write -o /tmp/st python)。我开始认为没有办法禁用此功能,但是要保持制表符完成而不复制来自的代码/usr/lib/python3.4/site.py
Lekensteyn 2014年

AFAIK,没有办法真正禁用它。
cuonglm

2

另一个〜/ .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代码。将以下代码编写到~/.pythonrcexport PYTHONSTARTUP=~/.pythonrc在您的Shell中进行设置以启用它。

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]是目录

每次您终止python shell时。退出状态仍为0

请注意,如果您将其保留为文件,则需要创建另一个文件并使其不可变, ~/.python_history


0

将以下内容放入文件并进行设置PYTHONSTARTUP(或调用该文件sitecustomize.py并使其可从进行访问PYTHONPATH

import readline
import atexit
import sys

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

这样,您仍然可以访问制表符完成和以前的历史记录,但是您输入的命令不会添加到历史记录文件中。


这似乎不起作用(Arch Linux上的Python 3.5.1),即使PYTHONSTARTUP确实执行了脚本,历史记录文件仍会在退出时写入。
Lekensteyn'2

我刚刚在Arch Linux虚拟机上对其进行了测试,并且工作正常:gist.github.com/berdario/640b3ab00b128fdf3338
berdario

0

这是我的方法(事实证明,它基本上是berdario方法的更可靠和Pythonic版本)。它仅禁用对的写入.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

Python 3.7.3。不工作 历史记录仍然记录。
Boann

0

我当前的解决方案(适用于最新版本的Python 3)阻止默认使用〜/ .python_history,但保留将历史记录显式写入给定文件的可能性(使用readline.write_history_file(filename)或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

它具有令人愉悦的(对我而言)副作用,它用解释程序的启动时间标记任何明确写入的历史记录。之所以能正常工作是因为可以在这里找到bug 5845的修复。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.