持久的 Python 命令行历史

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1186958/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:40:26  来源:igfitidea点击:

Persistent Python Command-Line History

interpreterpython

提问by Carl G

I'd like to be able to "up-arrow" to commands that I input in a previous Python interpreter. I have found the readlinemodule which offers functions like: read_history_file, write_history_file, and set_startup_hook. I'm not quite savvy enough to put this into practice though, so could someone please help? My thoughts on the solution are:

我希望能够“向上箭头”到我在以前的 Python 解释器中输入的命令。我发现readline它提供了类似的功能模块:read_history_filewrite_history_file,和set_startup_hook。我不太精明,无法将其付诸实践,所以有人可以帮忙吗?我对解决方案的想法是:

(1) Modify .login PYTHONSTARTUP to run a python script. (2) In that python script file do something like:

(1) 修改.login PYTHONSTARTUP 运行python脚本。(2) 在那个 python 脚本文件中执行如下操作:

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

(3) Whenever the interpreter exits, write the history to the file. I guess the best way to do this is to define a function in your startup script and exit using that function:

(3) 每当解释器退出时,将历史写入文件。我想最好的方法是在启动脚本中定义一个函数并使用该函数退出:

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

It's very annoying to have to exit using parentheses, though: ex(). Is there some python sugar that would allow ex(without the parens) to run the exfunction?

但是,必须使用括号退出非常烦人:ex(). 是否有一些 python 糖可以允许ex(没有括号)运行该ex函数?

Is there a better way to cause the history file to write each time? Thanks in advance for all solutions/suggestions.

有没有更好的方法让历史文件每次都写入?提前感谢所有解决方案/建议。

Also, there are two architectural choices as I can see. One choice is to have a unified command history. The benefit is simplicity (the alternative that follows litters your home directory with a lot of files.) The disadvantage is that interpreters you run in separate terminals will be populated with each other's command histories, and they will overwrite one another's histories. (this is okay for me since I'm usually interested in closing an interpreter and reopening one immediately to reload modules, and in that case that interpreter's commands will have been written to the file.) One possible solution to maintain separate history files per terminal is to write an environment variable for each new terminal you create:

此外,正如我所见,有两种架构选择。一种选择是拥有统一的命令历史记录。好处是简单(在您的主目录之后的替代方案中包含大量文件。)缺点是您在不同终端中运行的解释器将填充彼此的命令历史记录,并且它们将覆盖彼此的历史记录。(这对我来说没问题,因为我通常有兴趣关闭解释器并立即重新打开一个解释器以重新加载模块,在这种情况下,解释器的命令将被写入文件。)一种可能的解决方案,用于为每个终端维护单独的历史文件是为您创建的每个新终端编写一个环境变量:

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()

By decreasing the random key length from 16 to say 1 you could decrease the number of files littering your directories to 36 at the expense of possible (2.8% chance) of overlap.

通过将随机密钥长度从 16 减少到 1,您可以将目录中的文件数量减少到 36,但代价是可能(2.8% 的几率)重叠。

采纳答案by ars

I think the suggestions in the Python documentation pretty much cover what you want. Look at the example pystartup file toward the end of section 13.3:

我认为 Python 文档中的建议几乎涵盖了您想要的内容。查看第 13.3 节末尾的示例 pystartup 文件:

or see this page:

或查看此页面:

But, for an out of the box interactive shell that provides all this and more, take a look at using IPython:

但是,对于提供所有这些以及更多功能的开箱即用的交互式 shell,请看一下使用 IPython:

回答by Maxim Sloyko

Try using IPythonas a python shell. It already has everything you ask for. They have packages for most popular distros, so install should be very easy.

尝试使用IPython作为 python shell。它已经拥有您所要求的一切。他们有最流行的发行版的软件包,所以安装应该很容易。

回答by xuhdev

Persistent history has been supported out of the box since Python 3.4. See this bug report.

自 Python 3.4 以来,持久历史记录已被支持开箱即用。请参阅此错误报告

回答by not2qubit

Use PIP to install the pyreadlinepackage:

使用 PIP 安装pyreadline包:

pip install pyreadline

回答by jtpereyda

If all you want is to use interactive history substitution without all the file stuff, all you need to do is import readline:

如果您只想使用没有所有文件内容的交互式历史替换,您需要做的就是导入 readline:

import readline

And then you can use the up/down keys to navigate past commands. Same for 2 or 3.

然后您可以使用向上/向下键导航过去的命令。2 或 3 相同。

This wasn't clear to me from the docs, but maybe I missed it.

从文档中我不清楚这一点,但也许我错过了。