Comment voyez-vous l'historique complet des commandes dans Python interactif?

150

Je travaille sur l'interpréteur python par défaut sur Mac OS X, et j'ai Cmd+ K(effacé) mes commandes précédentes. Je peux les parcourir un par un en utilisant les touches fléchées. Mais y a-t-il une option comme l'option --history dans le shell bash, qui vous montre toutes les commandes que vous avez entrées jusqu'à présent?

Lavanya
la source
La historycommande shell est un programme comme les autres. Ce n'est pas une "option" dans la bashcommande.
Niloct
6
Pour être précis: historyest un shell intégré.
blinry
3
Pour iPython, la réponse est %history. Et l' -goption obtient des sessions antérieures .
Bob Stein
% history -g +% edit fonctionne mieux
Dyno Fu
Je viens de poser la question équivalente pour Windows 10
Josiah Yoder

Réponses:

251

Code pour imprimer l'historique complet:

Python 3

One-liner (copier-coller rapide):

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

(Ou version plus longue ...)

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

Python 2

One-liner (copier-coller rapide):

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

(Ou version plus longue ...)

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

Remarque : get_history_item()est indexé de 1 à n.

Dennis Golomazov
la source
31
Une doublure:import readline; print '\n'.join([str(readline.get_history_item(i)) for i in range(readline.get_current_history_length())])
Matt
24
Cette réponse (et son équivalent sans exemple) illustre à quel point les exemples sont importants pour les gens. Merci.
Tim S.
8
Cool! J'ai ajouté une history()fonction avec ce qui précède dans mon script de démarrage d'interpréteur Python (un script pointé par env. Var $PYTHONSTARTUP). À partir de maintenant, je peux simplement taper history()n'importe quelle session d'interprétation ;-)
sxc731
2
Chaque fois que j'oublie, comment cela se fait, je viens ici pour la réponse, merci Dennis.
Felipe Valdes
3
J'ai joué ce qui sait quand et je suis de retour pour attraper cette bonté une fois de plus. 👍🏽
Berto
45

Avec l'interpréteur python 3, l'historique est écrit
~/.python_history

Candide Guevara Marino
la source
Je n'ai pas ce répertoire et j'utilise Python 3.5.2
Ce serait pour les systèmes d'exploitation de type Unix. J'ai pu récupérer mon historique sur macOS aveccat ~/.python_history
Ryan H.
1
Merci pour cette réponse. J'ai trouvé plus tard ceci couvert dans la documentation ici: docs.python.org/3/library/site.html#readline-configuration
Jason V.
4
Malheureusement, l'historique ne semble pas être mis à jour lors de l'utilisation d'environnements virtuels: - /
ChrisFreeman
4
Vous avez besoin de quit()l'interprète pour que l'historique de la session en cours soit inclus dans~/.python_history
plexoos
9

Si vous souhaitez écrire l'historique dans un fichier:

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

La fonction d'aide donne:

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.
Martin Thoma
la source
Est-ce que cela persistera à travers les sessions python comme l'histoire de pry de ruby?
lacostenycoder
Peut-être que cette réponse a été écrite avant la fonction readline, mais pourquoi ne pas utiliser readline.write_history_file? @lacostenycoder Vous pouvez utiliser readline pour lire et écrire un fichier d'historique qui persiste.
Joe Holloway
@JoeHolloway Cool, merci! J'ai changé la réponse!
Martin Thoma
4

Comme ce qui précède ne fonctionne que pour python 2.x pour python 3.x (spécifiquement 3.5) est similaire mais avec une légère modification:

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

notez le supplément ()

(l'utilisation de scripts shell pour analyser .python_history ou l'utilisation de python pour modifier le code ci-dessus est une question de goût personnel et de situation à mon humble avis)

Jeff Cliff
la source
3
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 `ERREUR: La commande" python setup.py egg_info "a échoué avec le code d'erreur 1 dans C: \ Users \ dblack \ AppData \ Local \ Temp \ pip-install-s6m4zkdw \ readline`
bballdave025
1
@ bballdave025 Oui, vous ne pouvez pas pip install readline, mais readlineest installé par défaut sur Windows.
Josiah Yoder
Eh bien, cela facilite les choses. Merci @JosiahYoder
bballdave025
@ bballdave025 J'ai appris depuis qu'il n'est pas installé par défaut sur Windows, mais si vous suivez le lien, les instructions donnent des détails - quelque chose comme l'installation de pyreadline ou quelque chose.
Josiah Yoder
4

Dans IPython %history -gdevrait vous donner l'historique complet des commandes. La configuration par défaut enregistre également votre historique dans un fichier nommé .python_history dans votre répertoire utilisateur.

Yossarian42
la source
3

Une fonction simple pour obtenir l'historique similaire à la version unix / bash.

J'espère que cela aidera de nouvelles personnes.

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

Extrait: testé avec Python3. Faites-moi savoir s'il y a des problèmes avec python2. Échantillons:

Historique complet: ipyhistory()

10 derniers historiques: ipyhistory(10)

10 première histoire: ipyhistory(-10)

J'espère que cela aide les gars.

Doogle
la source
salut merci. J'ai transformé votre extrait de code dans un fichier xx.py. puis après avoir ouvert python, j'ai importé xx. ALORS j'ai essayé ipyhistory () mais il dit, ">>> ipyhistory Traceback (dernier appel en dernier): Fichier" <stdin> ", ligne 1, dans <module> NameError: le nom 'ipyhistory' n'est pas défini". Qu'est-ce qui ne va pas?
Chan Kim
J'ai révisé cela pour ne pas imprimer les numéros de ligne car ceux-ci me gênent généralement, mais j'ai aimé la capacité de limitation de ligne. (Même sous Unix, je les sortais habituellement cut -c 8.)
Josiah Yoder
1

@ Jason-V, ça aide vraiment, merci. puis, j'ai trouvé ces exemples et composé pour posséder un extrait.

#!/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 
dzNET
la source
1

Cela devrait vous donner les commandes imprimées sur des lignes séparées:

import readline
map(lambda p:print(readline.get_history_item(p)),
    map(lambda p:p, range(readline.get_current_history_length()))
)
Idea4life
la source
Pouvez-vous être plus précis sur le formatage du code? Êtes-vous en train de dire que les parenthèses ne correspondent pas?
Idea4life
J'ai corrigé le formatage avec une simple indentation. @AleksAndreev, vous pouvez supprimer votre vote défavorable.
ChrisFreeman
0

Rehash de la réponse de Doogle qui n'imprime pas les numéros de ligne, mais permet de spécifier le nombre de lignes à imprimer.

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))
Josiah Yoder
la source