Est-il possible d'aller dans ipython de code?
Question
Pour mes besoins de débogage, pdb
est assez bonne. Cependant, il serait beaucoup refroidisseur (et utile) si je pouvais aller dans ipython
. Est-ce ce possible?
La solution
Il y a un projet qui intègre ipdb
ipython dans le pdb standard, donc vous pouvez juste faire:
import ipdb; ipdb.set_trace()
Il est installable via le pip install ipdb
habituelle.
ipdb
est assez courte, donc au lieu de easy_installing vous pouvez également créer un fichier de ipdb.py
quelque part sur votre chemin Python et collez le texte suivant dans le fichier:
import sys
from IPython.Debugger import Pdb
from IPython.Shell import IPShell
from IPython import ipapi
shell = IPShell(argv=[''])
def set_trace():
ip = ipapi.get()
def_colors = ip.options.colors
Pdb(def_colors).set_trace(sys._getframe().f_back)
Autres conseils
Dans IPython 0.11, vous pouvez intégrer IPython directement dans votre code comme ceci
Votre programme pourrait ressembler à ceci
In [5]: cat > tmpf.py
a = 1
from IPython import embed
embed() # drop into an IPython session.
# Any variables you define or modify here
# will not affect program execution
c = 2
^D
Voici ce qui se passe lorsque vous l'exécutez (j'ai choisi arbitrairement pour l'exécuter dans une session ipython existante. Sessions Nesting de ipython comme celui-ci dans mon expérience peut provoquer des plantages).
In [6]:
In [6]: run tmpf.py
Python 2.7.2 (default, Aug 25 2011, 00:06:33)
Type "copyright", "credits" or "license" for more information.
IPython 0.11 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
In [1]: who
a embed
In [2]: a
Out[2]: 1
In [3]:
Do you really want to exit ([y]/n)? y
In [7]: who
a c embed
Si vous utilisez une version plus moderne de IPython (> 0.10.2), vous pouvez utiliser quelque chose comme
from IPython.core.debugger import Pdb
Pdb().set_trace()
Mais il est sans doute préférable d'utiliser juste ipdb
L'équivalent de
import pdb; pdb.set_trace()
avec IPython est quelque chose comme:
from IPython.ipapi import make_session; make_session()
from IPython.Debugger import Pdb; Pdb().set_trace()
Il est un peu bavard, mais bien de savoir si vous n'avez pas ipdb installé. L'appel make_session
est nécessaire de mettre en place une fois le schéma de couleurs, etc, et les appels set_trace
peut être placé n'importe où vous devez casser.
Normalement, quand je l'utilise ipython, je tourne le débogage automatique avec la commande « pdb » à l'intérieur.
Je lance alors mon script avec la commande « run myscript.py » dans le répertoire où se trouve mon script.
Si je reçois une exception, ipython arrête le programme à l'intérieur du débogueur. Consultez la commande d'aide pour la magie ipython commandes (% magie)
J'aime coller simplement celui-liner dans mes scripts où je veux mettre un point d'arrêt:
__import__('IPython').Debugger.Pdb(color_scheme='Linux').set_trace()
Une version plus récente peut utiliser:
__import__('IPython').core.debugger.Pdb(color_scheme='Linux').set_trace()
On dirait que les modules ont été bousculés un peu récemment. Sur IPython 0.13.1 les œuvres suivantes pour moi
from IPython.core.debugger import Tracer; breakpoint = Tracer()
breakpoint() # <= wherever you want to set the breakpoint
Bien hélas, il est tout assez sans valeur qtconsole.
Les versions plus récentes de IPython fournissent un mécanisme facile pour l'intégration et l'imbrication des sessions ipython dans tous les programmes Python. Vous pouvez suivre la recette suivante pour intégrer des séances ipython:
try:
get_ipython
except NameError:
banner=exit_msg=''
else:
banner = '*** Nested interpreter ***'
exit_msg = '*** Back in main IPython ***'
# First import the embed function
from IPython.frontend.terminal.embed import InteractiveShellEmbed
# Now create the IPython shell instance. Put ipshell() anywhere in your code
# where you want it to open.
ipshell = InteractiveShellEmbed(banner1=banner, exit_msg=exit_msg)
Ensuite, utilisez ipshell()
chaque fois que vous voulez tomber dans une coquille IPython. Cela vous permettra d'intégrer (et même nid) interprètes ipython dans votre code.
De ipython docs :
import IPython.ipapi
namespace = dict(
kissa = 15,
koira = 16)
IPython.ipapi.launch_new_instance(namespace)
va lancer un programme shell IPython. Il est évident que les valeurs dans les dict de namespace
ne sont que des valeurs fictives - il serait plus judicieux d'utiliser locals()
dans la pratique
Notez que vous devez coder en dur cette option; il ne va pas travailler la façon pdb
fait. Si c'est ce que vous voulez, la réponse de DoxaLogos est probablement plus comme ce que vous cherchez.
La façon rapide et facile:
from IPython.Debugger import Tracer
debug = Tracer()
Ensuite, il suffit d'écrire
debug()
où vous voulez commencer le débogage de votre programme.
Je devais google un couple si le temps les derniers jours afin d'ajouter une réponse ... il est parfois agréable de pouvoir exécuter un script normalement et ne tombent dans ipython / ipdb sur les erreurs, sans avoir à mettre des points d'arrêt de ipdb.set_trace()
en le code
ipython --pdb -c "%run path/to/my/script.py --with-args here"
(première pip install ipython
et pip install ipdb
bien sûr)
Ceci est assez simple:
ipython some_script.py --pdb
Il a besoin d'installation ipython, généralement cela fonctionne:
pip install ipython
J'utilise ipython3 au lieu de ipython, donc je sais que c'est une version récente de Python.
Ceci est simple à retenir parce que vous utilisez juste ipython au lieu de python, et d'ajouter --pdb à la fin.