79 votes

Comment copier à partir d'une session IPython sans les invites de terminal

Fréquemment, mon flux de travail implique le nettoyage/manipulation de données dans une coquille IPython. Cela est devenu particulièrement merveilleux depuis la version 5.0 d'IPython avec toutes les superbes améliorations de l'interface de terminal. Donc, disons que je fais une tentative pour améliorer des données non structurées :

In [11]: for i, (num, header, txt) in enumerate(data):
    ...:     header = [e.strip() for e in header.strip().split('\n')]
    ...:     header[4] = header[4].strip(',').split(',')
    ...:     data[i] = (num, header, txt)
    ...:

Fantastique, ça fonctionne ! Mais maintenant, j'aimerais vraiment ajouter ceci à un script dans mon éditeur. Si je copie et colle depuis mon terminal, je capture tout le bazar à gauche. Je peux nettoyer cela plus ou moins facilement dans un éditeur, mais ce serait génial si je pouvais copier le code directement dans mon presse-papiers depuis le terminal sans toucher à la souris et sans attraper le truc supplémentaire non plus. Existe-t-il une telle fonctionnalité dans IPython ?

1 votes

Il semble que certaines personnes aient implémenté la fonctionnalité, mais elle ne semble pas être fournie avec IPython.

1 votes

Si vous ne voulez pas personnaliser votre configuration IPython, print(In[11]) devrait vous donner quelque chose à copier sans les éléments superflus sur la gauche.

0 votes

@user2357112 Hm, bien que ce ne soit pas l'idéal, cela pourrait fonctionner pour moi. Si vous l'ajoutez comme réponse et qu'aucune meilleure option n'apparaît, je l'accepterai.

107voto

m00am Points 2925

Vous pouvez utiliser la magie %history pour extraire les parties intéressantes de votre session. Elles seront affichées dans le terminal sans aucun des éléments superflus.

Exemple

In [1]: import numpy as np    
In [2]: a = np.random(10)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
 in ()
----> 1 a = np.random(10)

TypeError: 'module' object is not callable

In [3]: a = np.random.random(10)
In [4]: for i in a:
   ...:     print(i)
   ...:     
0.688626523886
[...]
0.341394850998

Si je veux sauvegarder une partie de la session ci-dessus je peux utiliser:

In [5]: %history 1 3-4

import numpy as np
a = np.random.random(10)
for i in a:
    print(i)

Dans l'exemple ci-dessus, j'ai utilisé %history 1 3-4 pour rassembler toutes les commandes que je souhaite conserver et omettre celles dont je n'ai pas besoin (Ligne 2, celle avec l'erreur). Maintenant, vous avez une version de votre session qui peut être copiée facilement.

Écriture dans un fichier

Vous pouvez également écrire directement ceci dans un fichier en utilisant le paramètre -f NOM_FICHIER.

In [8]: %history 1 3-4 -f /tmp/foo.py

Mais attention, cela va écraser les fichiers existants. Plus de détails peuvent être trouvés dans la documentation de la magie %history.

0 votes

C'est une fonction utile, bien qu'elle donne aussi les commandes que nous utilisons en sortie, par exemple si j'utilise %history, cela l'affichera également la prochaine fois. Je pense que c'est ce que history fait.

20voto

juanpa.arrivillaga Points 35811

Donc, j'ai enfin trouvé une excellente solution qui est essentiellement exactement ce que je voulais : Utiliser le mode Vi dans IPython. Sur la version 5, cela nécessite :

$ ipython --TerminalInteractiveShell.editing_mode=vi

Maintenant je peux utiliser le mode visuel similaire à vi et copier ce dont j'ai besoin !

Ce qui conduit au nouveau alias suivant dans mon .bash_profile/.bash_rc :

alias vpython='ipython --TerminalInteractiveShell.editing_mode=vi'

2 votes

Au lieu d'utiliser un alias, vous pouvez ajouter c.TerminalInteractiveShell.editing_mode = 'vi' à ~/.ipython/profile_default/ipython_config.py. Crédit à et plus de détails ici.

5 votes

Excellente réponse mais comment copier le code avec des invites de terminal ??

2 votes

La fonctionnalité de copie vers le presse-papiers standard ne semble pas fonctionner en mode vim IPython comme c'est le cas dans Vim. "+y ne fonctionne pas.

13voto

La commande magique save [documentation] enregistre les lignes d'entrée que vous souhaitez dans un fichier ; l'option -a est pour le mode "ajout" pour que les lignes soient ajoutées à la fin du fichier au lieu d'écraser le fichier. Je l'utilise tout le temps.

Avec votre exemple :

%save -a myfile.py 11
# le '%' n'est pas nécessaire
save -a myfile.py 11

Ensuite, vous pouvez continuer à coder dans IPython.

Quand il y a une autre commande que vous voulez écrire dans le même fichier, vous pouvez simplement taper save puis utiliser la flèche vers le haut pour ramener la dernière utilisation de "save" (ainsi l'option -a et le nom de fichier sont déjà là) et il suffit de modifier le numéro de ligne.

Notez que vous pouvez donner plusieurs lignes à enregistrer ainsi que des plages de lignes :

save -a myfile.py 15 18 19-25

0 votes

Ce que j'aime dans cette solution, c'est qu'elle affiche également le code sans invite de terminal dans l'interpréteur iPython.

4voto

Dans le shell, vous pouvez d'abord convertir le fichier IPython en un fichier Python normal (.py) et ensuite effectuer le nettoyage :

http://ipython.org/ipython-doc/3/notebook/nbconvert.html (voir le format --to script)

Vous pouvez également télécharger le fichier dans l'éditeur de notebook en tant que fichier Python et effectuer le nettoyage après cette étape.

0 votes

... Je ne pense pas que vous compreniez, il n'y a pas de fichier IPython (par cela, je suppose que vous voulez dire notebook Jupyter). Tout l'intérêt est que je suis dans un terminal, utilisant le shell, et idéalement, je ne veux pas du tout utiliser ma souris. La magie %history s'en approchait le plus, c'est pourquoi je l'ai acceptée, mais elle nécessite toujours une souris, malheureusement.

0 votes

Oui, vous avez raison, fichier de bloc-notes Jupyter (format ipynb). Je pensais que vous pourriez exécuter le type de commande suivant dans le terminal : $ ipython nbconvert --to script .ipynb pour créer un fichier utilisable à nettoyer dans le terminal (mes excuses, je débute juste avec Python) J'ai appris de votre message.

0 votes

Oui, malheureusement, je ne travaille pas avec un notebook jupyter, je travaille dans un REPL. Parfois je le fais, mais ensuite, le problème est sans importance en raison des outils que vous avez mentionnés, et du fait que le code est déjà dans un format texte nettoyé.

1voto

Sean McSomething Points 4383

Je ne pense pas que les applications de terminal aient vraiment accès au presse-papiers. Vous allez devoir utiliser la souris. Comment le faire dépend du terminal que vous utilisez. La plupart des terminaux modernes ont un type de mode "sélection rectangulaire" ou "sélection de bloc".

Avec Windows, la sélection rectangulaire est la valeur par défaut pour cmd.exe et Powershell. Si vous utilisez mintty de Cygwin, maintenez Alt puis sélectionnez la région avec la souris. Il en va de même pour PuTTY.

Sous Linux (que je n'ai pas sous les yeux - prenez ces informations avec un grain de sel), xterm ne le prend pas en charge, le Terminal Gnome utilise Ctrl comme modificateur, et le Konsole de KDE utilise Ctrl+Alt.

Pour le Terminal d'OS X, Internet me dit que vous utilisez tout en cliquant.

D'autres terminaux (et GNU Screen) ont probablement cette fonctionnalité, c'est juste une question de comprendre comment l'activer.

0 votes

Les applications de terminal ont le même accès au presse-papiers que n'importe quelle autre application.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X