更改`~/.python_history`的位置

更改`~/.python_history`的位置

我想保留该功能,但将位置更改~/.python_history$XDG_DATA_HOME/python/python_history.

给了我以下想法:我可以创建$XDG_CONFIG_HOME/python/pythonrc并指向$PYTHONSTARTUP它。在那里我想替换函数readline.read_history_file,readline.write_history_filereadline.append_history_file

有没有办法用包含自定义参数的函数本身替换这些函数filename

如果没有,您还有其他想法如何解决这个问题吗?

答案1

像你和 ctrl-alt-delor 一样,我寻找神秘的干净主目录。对的调用readline.write_history_file注册为在退出时运行site.py(在我的 arch 系统上,位于/usr/lib/python3.9/site.py):

if readline.get_current_history_length() == 0:
    # If no history was loaded, default to .python_history.
    # The guard is necessary to avoid doubling history size at
    # each interpreter exit when readline was already configured
    # through a PYTHONSTARTUP hook, see:
    # http://bugs.python.org/issue5845#msg198636
    history = os.path.join(os.path.expanduser('~'),
                           '.python_history')
    try:
        readline.read_history_file(history)
    except OSError:
        pass

    def write_history():
        try:
            readline.write_history_file(history)
        except OSError:
            # bpo-19891, bpo-41193: Home directory does not exist
            # or is not writable, or the filesystem is read-only.
            pass

    atexit.register(write_history)

您可以在 PYTHONSTARUP 中复制此内容,但使用 python 历史记录的自定义位置。这是我的(但如果您愿意,我确信您可以使用环境替换来使用适当的 XDG 目录。:

import os
import atexit
import readline

history = os.path.join(os.path.expanduser('~'), '.cache/python_history')
try:
    readline.read_history_file(history)
except OSError:
    pass

def write_history():
    try:
        readline.write_history_file(history)
    except OSError:
        pass

atexit.register(write_history)

可以覆盖 write_history_file 函数,但它非常老套(您需要它来忽略它代替自定义参数给出的参数),所以我认为这是最好的解决方案。如果这不起作用,请尝试在自定义 python 历史记录文件中创建一个虚拟条目,以便历史记录长度大于 0。

答案2

唯一的那个xdg-ninja用途(为了方便粘贴在这里):

导出环境变量:

export PYTHONSTARTUP="/etc/python/pythonrc"

创造/etc/python/pythonrc

import os
import atexit
import readline
from pathlib import Path

if readline.get_current_history_length() == 0:
    state_home = os.environ.get("XDG_STATE_HOME")
    if state_home is None:
        state_home = Path.home() / ".local" / "state"
    else:
        state_home = Path(state_home)

    history_path = state_home / "python_history"
    if history_path.is_dir():
        raise OSError(f"'{history_path}' cannot be a directory")

    history = str(history_path)

    try:
        readline.read_history_file(history)
    except OSError:  # Non existent
        pass

    def write_history():
        try:
            readline.write_history_file(history)
        except OSError:
            pass

    atexit.register(write_history)

答案3

这将在 Python 3.13 中通过合并实现公关 13208。它添加了一个PYTHON_HISTORY可用于自定义历史文件位置的环境变量。

export PYTHON_HISTORY=~/.local/share/python/history

答案4

我对此的看法受到启发其他 答案:

# Enable custom ~/.python_history location on Python interactive console
# Set PYTHONSTARTUP to this file on ~/.profile or similar for this to work
# https://docs.python.org/3/using/cmdline.html#envvar-PYTHONSTARTUP
# https://docs.python.org/3/library/readline.html#example
# https://github.com/python/cpython/blob/main/Lib/site.py @ enablerlcompleter()
# https://unix.stackexchange.com/a/675631/4919

import atexit
import os
import readline
import time


def write_history(path):
    import os
    import readline
    try:
        os.makedirs(os.path.dirname(path), mode=0o700, exist_ok=True)
        readline.write_history_file(path)
    except OSError:
        pass


history = os.path.join(os.environ.get('XDG_CACHE_HOME') or
                       os.path.expanduser('~/.cache'),
                       'python_history')
try:
    readline.read_history_file(history)
except FileNotFoundError:
    pass

# Prevents creation of default history if custom is empty
if readline.get_current_history_length() == 0:
    readline.add_history(f'# History created at {time.asctime()}')

atexit.register(write_history, history)
del (atexit, os, readline, time, history, write_history)

相关内容