持久化Python命令行历史

15 投票
5 回答
13236 浏览
提问于 2025-04-15 13:11

我想在之前使用的Python解释器中,能够通过“上箭头”来查看我输入过的命令。我发现了一个叫做readline的模块,它提供了一些功能,比如:read_history_filewrite_history_fileset_startup_hook。不过我对这些还不是很熟悉,所以能不能请人帮我一下?我对解决方案的想法是:

(1) 修改 .login 文件中的 PYTHONSTARTUP,让它运行一个Python脚本。

(2) 在这个Python脚本文件里做一些事情,比如:

def command_history_hook():
    import readline
    readline.read_history_file('.python_history')
command_history_hook()

(3) 每次解释器退出时,把历史记录写入文件。我想最好的方法是在你的启动脚本中定义一个函数,然后用这个函数退出:

def ex():
    import readline
    readline.write_history_file('.python_history')
    exit()

不过,用括号退出真的很烦:ex()。有没有什么方法可以让我只输入ex(不带括号)就能运行ex这个函数呢?

有没有更好的方法可以让历史记录文件每次都写入呢?提前谢谢所有的解决方案和建议。

另外,我看到有两种架构选择。一种选择是有一个统一的命令历史记录。这样做的好处是简单(而另一种选择会让你的主目录里充满很多文件)。缺点是你在不同终端中运行的解释器会互相混合命令历史,并且会覆盖彼此的历史记录。(对我来说这没关系,因为我通常是在关闭一个解释器后立即重新打开一个来重新加载模块,这样那个解释器的命令就会被写入文件。)保持每个终端有独立历史记录文件的一个可能解决方案是为你创建的每个新终端写一个环境变量:

def random_key()
    ''.join([choice(string.uppercase + string.digits) for i in range(16)])

def command_history_hook():
    import readline
    key = get_env_variable('command_history_key')
    if key:
        readline.read_history_file('.python_history_{0}'.format(key))
    else:
        set_env_variable('command_history_key', random_key())

def ex():
    import readline
    key = get_env_variable('command_history_key')
    if not key:
        set_env_variable('command_history_key', random_key())
    readline.write_history_file('.python_history_{0}'.format(key))
    exit()

通过把随机密钥的长度从16减少到1,你可以把目录里的文件数量减少到36,但这样可能会有重叠的风险(大约2.8%的机会)。

5 个回答

1

从Python 3.4开始,程序就自带了持久化历史记录的功能。这意味着你在使用Python时,可以保存你之前输入的命令,方便下次使用。想了解更多,可以看看这个错误报告

4

试试用 IPython 作为你的Python命令行工具。它已经包含了你需要的所有功能。大多数流行的操作系统都有相应的安装包,所以安装起来非常简单。

13

我觉得Python文档里的建议基本上涵盖了你想要的内容。你可以看看第13.3节末尾的pystartup示例文件:

或者查看这个页面:

不过,如果你想要一个开箱即用的交互式命令行,能提供这些功能以及更多,可以看看IPython:

撰写回答