ChatGPT解决这个技术问题 Extra ChatGPT

How do you see the entire command history in interactive Python?

I'm working on the default python interpreter on Mac OS X, and I Cmd+K (cleared) my earlier commands. I can go through them one by one using the arrow keys. But is there an option like the --history option in bash shell, which shows you all the commands you've entered so far?

The history shell command is a program like any other. It isn't an "option" in bash command.
To be precise: history is a shell builtin.
For iPython the answer is %history. And the -g option gets earlier sessions.
%history -g + %edit works best

D
Dennis Golomazov

Code for printing the entire history:

Python 3

One-liner (quick copy and paste):

import readline; print('\n'.join([str(readline.get_history_item(i + 1)) for i in range(readline.get_current_history_length())]))

(Or longer version...)

import readline
for i in range(readline.get_current_history_length()):
    print (readline.get_history_item(i + 1))

Python 2

One-liner (quick copy and paste):

import readline; print '\n'.join([str(readline.get_history_item(i + 1)) for i in range(readline.get_current_history_length())])

(Or longer version...)

import readline
for i in range(readline.get_current_history_length()):
    print readline.get_history_item(i + 1)

Note: get_history_item() is indexed from 1 to n.


One liner: import readline; print '\n'.join([str(readline.get_history_item(i)) for i in range(readline.get_current_history_length())])
This answer (and its non-example counterpart) exemplifies how important examples are to people. Thanks.
Cool! I've added an history() function with the above in my Python interpreter startup script (a script that's pointed to by env. var $PYTHONSTARTUP). From now on, I can simply type history() in any interpreter session ;-)
Everytime I forget, how this is done, I come here for the answer, thank you Dennis.
I starred this who knows when and I'm back to snag this goodness one more time. 👍🏽
I
Ignacio Vazquez-Abrams

Use readline.get_current_history_length() to get the length, and readline.get_history_item() to view each.


See answer by @dennis Golomazov, for an even better answer.
C
Candide Guevara Marino

With python 3 interpreter the history is written to
~/.python_history


I don't have this directory and I use Python 3.5.2
This would be for Unix-like OSes. I was able to retrieve my history on macOS with cat ~/.python_history
Thanks for this answer. I later found this covered in the docs here: docs.python.org/3/library/site.html#readline-configuration
Unfortunately, history doesn't seem to get updated when using virtual environments :-/
You need to quit() the interpreter for the current session history to be included in ~/.python_history
M
Martin Thoma

If you want to write the history to a file:

import readline
readline.write_history_file('python_history.txt')

The help function gives:

Help on built-in function write_history_file in module readline:

write_history_file(...)
    write_history_file([filename]) -> None
    Save a readline history file.
    The default filename is ~/.history.

will this persist across python sessions like ruby's pry history?
Maybe this answer was written before the readline function, but why not use readline.write_history_file ? @lacostenycoder You can use readline to both read and write a history file that persists.
Y
Yossarian42

In IPython %history -g should give you the entire command history. The default configuration also saves your history into a file named .python_history in your user directory.


For help run %history?. Nice tips there.
To save to a file run: from datetime import datetime; file01="qtconsole_hist_"+datetime.today().strftime('%Y%m%d%H%M%S')+".py"; and %history -f $file01
A file enables to see by lines, and not cells: %hist -l 10 -n # prints last 10 cells VS !tail -n 10 $file01 # prints last 10 lines
I wish this answer got more upvotes. Such an amazing feature! Especially that you can search by sessions. Thanks for sharing it.
J
Jeff Cliff

Since the above only works for python 2.x for python 3.x (specifically 3.5) is similar but with a slight modification:

import readline
for i in range(readline.get_current_history_length()):
    print (readline.get_history_item(i + 1))

note the extra ()

(using shell scripts to parse .python_history or using python to modify the above code is a matter of personal taste and situation imho)


Win10 C:\>python -m pip install readline => Collecting readline \n Downloading https://files.pythonhosted.org/packages/f4/01/2cf081af8d880b44939a5f1b446551a7f8d59eae414277fd0c303757ff1b/readline-6.2.4.1.tar.gz (2.3MB) \n |████████████████████████████████| 2.3MB 1.7MB/s \n ERROR: Complete output from command python setup.py egg_info: \n ERROR: error: this module is not meant to work on Windows \n ---------------------------------------- \n `ERROR: Command "python setup.py egg_info" failed with error code 1 in C:\Users\dblack\AppData\Local\Temp\pip-install-s6m4zkdw\readline`
@bballdave025 Yes, you can't pip install readline, but readline is installed by default on Windows.
Well, that makes things easier. Thanks @JosiahYoder
@bballdave025 I since learned that it isn't installed by default on windows, but if you follow the link, the instructions give details -- something like installing pyreadline or something.
d
dzNET

@Jason-V, it really help, thanks. then, i found this examples and composed to own snippet.

#!/usr/bin/env python3
import os, readline, atexit
python_history = os.path.join(os.environ['HOME'], '.python_history')
try:
  readline.read_history_file(python_history)
  readline.parse_and_bind("tab: complete")
  readline.set_history_length(5000)
  atexit.register(readline.write_history_file, python_history)
except IOError:
  pass
del os, python_history, readline, atexit 

Important! This is only saving history after you exit from the REPL.
In addition, it need to be put into your PYTHONSTARTUP to work as expected. If you use ironPython, you don't need this.
J
Josiah Yoder

A simple function to get the history similar to unix/bash version.

Hope it helps some new folks.

def ipyhistory(lastn=None):
    """
    param: lastn Defaults to None i.e full history. If specified then returns lastn records from history.
           Also takes -ve sequence for first n history records.
    """
    import readline
    assert lastn is None or isinstance(lastn, int), "Only integers are allowed."
    hlen = readline.get_current_history_length()
    is_neg = lastn is not None and lastn < 0
    if not is_neg:
        flen = len(str(hlen)) if not lastn else len(str(lastn))
        for r in range(1,hlen+1) if not lastn else range(1, hlen+1)[-lastn:]:
            print(": ".join([str(r if not lastn else r + lastn - hlen ).rjust(flen), readline.get_history_item(r)]))
    else:
        flen = len(str(-hlen))
        for r in range(1, -lastn + 1):
            print(": ".join([str(r).rjust(flen), readline.get_history_item(r)]))

Snippet: Tested with Python3. Let me know if there are any glitches with python2. Samples:

Full History : ipyhistory()

Last 10 History: ipyhistory(10)

First 10 History: ipyhistory(-10)

Hope it helps fellas.


hi, thanks. I made your code snippet into a file xx.py. then after opening python, I did import xx. THen I tried ipyhistory() but it says, ">>> ipyhistory Traceback (most recent call last): File "", line 1, in NameError: name 'ipyhistory' is not defined". What's wrong?
I've revised this to not print line numbers since those usually get in the way for me, but I liked the line-limiting ability. (Even on Unix, I usually cut -c 8 them out.)
C
ChrisFreeman

This should give you the commands printed out in separate lines:

import readline
map(lambda p:print(readline.get_history_item(p)),
    map(lambda p:p, range(readline.get_current_history_length()))
)

Can you please be more specific on formatting the code? Are you saying the parentheses are not matching?
I've fixed the formatting with some simple indentation. @AleksAndreev you may remove your downvote.
J
Josiah Yoder

Rehash of Doogle's answer that doesn't printline numbers, but does allow specifying the number of lines to print.

def history(lastn=None):
    """
    param: lastn Defaults to None i.e full history. If specified then returns lastn records from history.
           Also takes -ve sequence for first n history records.
    """
    import readline
    assert lastn is None or isinstance(lastn, int), "Only integers are allowed."
    hlen = readline.get_current_history_length()
    is_neg = lastn is not None and lastn < 0
    if not is_neg:
        for r in range(1,hlen+1) if not lastn else range(1, hlen+1)[-lastn:]:
            print(readline.get_history_item(r))
    else:
        for r in range(1, -lastn + 1):
            print(readline.get_history_item(r))