D'après ce que j'ai lu, il existe deux façons de déboguer le code en Python:
Avec un débogueur traditionnel tel que
pdb
ouipdb
. Cela prend en charge les commandes telles quec
forcontinue
,n
forstep-over
,s
forstep-into
etc.), mais vous n'avez pas d'accès direct à un shell IPython qui peut être extrêmement utile pour l'inspection d'objets.Utiliser IPython en incorporant un shell IPython dans votre code. Vous pouvez le faire
from ipython import embed
, puis utiliserembed()
dans votre code. Lorsque votre programme / script atteint uneembed()
instruction, vous êtes placé dans un shell IPython. Cela permet l'inspection complète des objets et le test du code Python en utilisant tous les goodies IPython. Cependant, lors de l'utilisation,embed()
vous ne pouvez plus parcourir le code pas à pas avec des raccourcis clavier pratiques.
Existe-t-il un moyen de combiner le meilleur des deux mondes? C'est à dire
- Soyez capable de parcourir votre code pas à pas avec les raccourcis clavier pratiques pdb / ipdb.
- À chaque étape de ce type (par exemple sur une instruction donnée), ayez accès à un shell IPython à part entière .
Débogage IPython comme dans MATLAB:
Un exemple de ce type de "débogage amélioré" peut être trouvé dans MATLAB, où l'utilisateur a toujours un accès complet au moteur / shell MATLAB, et il peut toujours pas à pas dans son code, définir des points d'arrêt conditionnels, etc. ce que j'ai discuté avec d'autres utilisateurs, c'est la fonctionnalité de débogage qui manque le plus aux gens lors du passage de MATLAB à IPython.
Débogage IPython dans Emacs et autres éditeurs:
Je ne veux pas rendre la question trop précise, mais je travaille principalement dans Emacs, donc je me demande s'il y a un moyen d'y intégrer cette fonctionnalité. Idéalement , Emacs (ou l'éditeur) permettrait au programmeur de définir des points d'arrêt n'importe où sur le code et de communiquer avec l'interpréteur ou le débogueur pour qu'il s'arrête à l'emplacement de votre choix, et amener un interpréteur IPython complet à cet emplacement.
!
commande qui exécute n'importe quelle commande python au point d'arrêtRéponses:
Vous pouvez utiliser la
%pdb
magie d'IPython . Appelez simplement%pdb
IPython et lorsqu'une erreur se produit, vous êtes automatiquement redirigé versipdb
. Bien que vous n'ayez pas le pas immédiatement, vous êtesipdb
après.Cela facilite le débogage des fonctions individuelles, car vous pouvez simplement charger un fichier avec
%load
, puis exécuter une fonction. Vous pouvez forcer une erreur avec unassert
à la bonne position.%pdb
est une ligne magique. Appelez comme%pdb on
,%pdb 1
,%pdb off
ou%pdb 0
. S'il est appelé sans argument, il fonctionne comme une bascule.la source
ipython --pdb file.py -- args
et être déposé sur ipdb en cas d'exception. Cela pourrait valoir la peine d’ajouter à la réponse.Et ipdb.set_trace ()? Dans votre code:
import ipdb; ipdb.set_trace()
mise à jour : maintenant en Python 3.7, nous pouvons écrire
breakpoint()
. Cela fonctionne de la même manière, mais il obéit également à laPYTHONBREAKPOINT
variable d'environnement. Cette fonctionnalité provient de ce PEP .Cela permet une inspection complète de votre code et vous avez accès à des commandes telles que
c
(continuer),n
(exécuter la ligne suivante),s
(entrer dans la méthode au point) et ainsi de suite.Voir le référentiel ipdb et une liste de commandes . IPython est maintenant appelé (modifier: une partie de) Jupyter .
ps: notez qu'une commande ipdb est prioritaire sur le code python. Donc, pour écrire,
list(foo)
vous en aurez besoinprint list(foo)
.De plus, si vous aimez l'invite ipython (ses modes emacs et vim, son historique, ses complétions,…), il est facile d'obtenir la même chose pour votre projet car il est basé sur la boîte à outils d'invite python .
la source
ipdb
dans Emacs en utilisantRealGUD
etisend-mode
faire exactement ce que l'OP demande.breakpoint()
est merveilleux. Dans PyCharm, il vous dépose même dans le débogueur PyCharm. C'est également un moyen rapide d'accéder au débogueur PyCharm à partir de fonctions collées dans la console.(Mise à jour du 28 mai 2016) Utilisation de RealGUD dans Emacs
Pour n'importe qui dans Emacs, ce fil montre comment accomplir tout ce qui est décrit dans l'OP (et plus) en utilisant
ipdb
).isend-mode
.La combinaison de ces deux packages est extrêmement puissante et permet de recréer exactement le comportement décrit dans l'OP et d'en faire encore plus.
Plus d'informations sur l'article wiki de RealGUD pour ipdb.
Réponse originale:
Après avoir essayé de nombreuses méthodes différentes pour déboguer Python, y compris tout ce qui est mentionné dans ce fil, l'un de mes moyens préférés de déboguer Python avec IPython est d'utiliser des shells intégrés.
Définition d'un shell IPython intégré personnalisé:
Ajoutez ce qui suit sur un script à votre
PYTHONPATH
, afin que la méthodeipsh()
devienne disponible.Ensuite, chaque fois que je veux déboguer quelque chose dans mon code, je place
ipsh()
juste à l'endroit où je dois faire l'inspection d'objet, etc. Par exemple, disons que je veux déboguermy_function
ci-dessousEn l'utilisant:
puis j'invoque
my_function(2)
de l'une des manières suivantes:Quelle que soit la façon dont je l'invoque, l'interprète s'arrête à la ligne qui dit
ipsh()
. Une fois que vous avez terminé, vous pouvez le faireCtrl-D
et Python reprendra l'exécution (avec toutes les mises à jour de variables que vous avez effectuées). Notez que, si vous exécutez le code à partir d'un IPython standard le shell IPython (cas 2 ci-dessus), le nouveau shell IPython sera imbriqué dans celui à partir duquel vous l'avez appelé, ce qui est parfaitement bien, mais il est bon d'en être conscient. Quoi qu'il en soit, une fois que l'interpréteur s'arrête à l'emplacement deipsh
, je peux inspecter la valeur dea
(quel être2
), voir quelles fonctions et quels objets sont définis, etc.Le problème:
La solution ci-dessus peut être utilisée pour que Python s'arrête où vous le souhaitez dans votre code, puis vous place dans un interpréteur IPython à part entière. Malheureusement, il ne vous permet pas d'ajouter ou de supprimer des points d'arrêt une fois que vous avez appelé le script, ce qui est très frustrant. À mon avis, c'est la seule chose qui empêche IPython de devenir un excellent outil de débogage pour Python.
Le mieux que vous puissiez faire pour le moment:
Une solution de contournement consiste à placer
ipsh()
a priori aux différents emplacements où vous voulez que l'interpréteur Python lance un shell IPython (ie abreakpoint
). Vous pouvez alors "sauter" entre différents "points d'arrêt" prédéfinis et codés en dur avecCtrl-D
, ce qui quitterait le shell IPython intégré actuel et s'arrêterait à nouveau chaque fois que l'interpréteur frappera le prochain appel àipsh()
.Si vous suivez cette route, une façon de quitter le "mode de débogage" et d'ignorer tous les points d'arrêt suivants est d'utiliser
ipshell.dummy_mode = True
ce qui fera en sorte que Python ignore toutes les instanciations ultérieures de l'ipshell
objet que nous avons créé ci-dessus.la source
import inspect
avant que cela fonctionne. La personnalisation de la ligne de commande semble être interrompue pour moi.import ipdb; ipdb.set_trace()
? Peut-être que quelque chose me manque, mais je ne vois pas l'avantage de votre méthode beaucoup plus compliquée.Vous pouvez démarrer la session IPython à partir de pudb et revenir à la session de débogage comme vous le souhaitez.
BTW, ipdb utilise IPython dans les coulisses et vous pouvez réellement utiliser les fonctionnalités IPython telles que la complétion TAB et les commandes magiques (celle commence par
%
). Si vous êtes d'accord avec ipdb, vous pouvez le démarrer à partir d'IPython en utilisant des commandes telles que%run
et%debug
. La session ipdb est en fait meilleure que celle d'IPython ordinaire dans le sens où vous pouvez monter et descendre dans la trace de pile, etc. Que manque-t-il dans ipdb pour "l'inspection d'objets"?De plus, python.el fourni avec Emacs> = 24.3 a un bon support ipdb.
la source
M-x ansi-term
tampon séparé , puis j'utilise isend-mode pour lier mes tampons source au tampon IPython afin que je puisse envoyer du code à l'interpréteur IPython avec un raccourci clavier qui envoie automatiquement la%paste
magie au tampon IPython. Cela me permet de tester rapidement des régions dans IPython. J'exécute toujours mes programmes à partir de ce shell IPython avecrun
et utiliseembed()
pour arrêter.ipdb
session de débogage en utilisantpython.el
et avoir des choses commesend-region
etc. dans le shell correspondant? En général, où puis-je trouver plus d'informations à ce sujet?%run
ou%debug
. Je suppose que çaimport ipdb; ipdb.set_trace()
marche aussi. Je ne pense pas que vous puissiez envoyer plusieurs lignes à ipdb. C'est la limitation d'ipdb. Mais le%paste
truc fonctionne probablement . Vous pouvez envoyer une demande de fonctionnalité à IPython dev.Il semble que l'approche de la réponse de @ gaborous soit obsolète .
La nouvelle approche semble être:
la source
ipdb
instructions dans le shell ipython, lors du débogage?Préfixer un "!" Le symbole des commandes que vous tapez dans pdb semble avoir le même effet que de faire quelque chose dans un shell IPython. Cela fonctionne pour accéder à l'aide pour une certaine fonction, ou même des noms de variables. Peut-être que cela vous aidera dans une certaine mesure. Par exemple,
Mais! Help (numpy.transpose) vous donnera la page d'aide attendue sur numpy.transpose. De même pour les noms de variables, disons que vous avez une variable l, taper "l" dans pdb liste le code, mais! L affiche la valeur de l.
la source
Avez-vous essayé cette astuce ?
la source
Vous pouvez commencer
IPython
de l'intérieuripdb
!Induire le
ipdb
débogueur 1 :Entrez IPython depuis la
ipdb>
console 2 :Revenez à la
ipdb>
console de l'intérieurIPython
:Si vous avez la chance d'utiliser Emacs, les choses peuvent être rendues encore plus pratiques!
Cela nécessite l'utilisation de
M-x shell
. À l'aide deyasnippet
et bm , définissez l'extrait de code suivant. Cela remplacera le texteipdb
dans l'éditeur par laset-trace
ligne. Après avoir inséré l'extrait de code, la ligne sera mise en surbrillance afin qu'elle soit facilement visible et navigable. UtilisezM-x bm-next
pour naviguer.1 Tout sur une seule ligne pour une suppression facile. Comme
imports
cela n'arrive qu'une seule fois, ce formulaire garantitipdb
qu'il sera importé lorsque vous en aurez besoin sans frais supplémentaires.2 Vous pouvez vous épargner de la saisie en important
IPython
dans votre.pdbrc
fichier :Cela vous permet d'appeler simplement
embed()
de l'intérieuripdb
(bien sûr, uniquement lorsque IPython est installé).la source
Une option consiste à utiliser un IDE comme Spyder qui devrait vous permettre d'interagir avec votre code pendant le débogage (en utilisant une console IPython, en fait). En fait, Spyder ressemble beaucoup à MATLAB, ce qui, je suppose, était intentionnel. Cela inclut les inspecteurs de variables, l'édition de variables, l'accès intégré à la documentation, etc.
la source
la bonne réponse, facile, cool et exacte à la question est d'utiliser la macro% run avec l'option -d.
la source
%save /tmp/foo.py x-y
le code que je veux exécuter et déboguer, puis%run -d /tmp/foo.py
définir le point d'arrêt où je veux. Très bonne réponse!Si vous tapez exit () dans la console embed (), le code continue et passe à la ligne embed () suivante.
la source
L' EDI Pyzo a des capacités similaires à celles demandées par l'OP. Vous n'avez pas besoin de démarrer en mode débogage. De la même manière que MATLAB, les commandes sont exécutées dans le shell. Lorsque vous configurez un point d'arrêt dans une ligne de code source, l'EDI arrête l'exécution à cet endroit et vous pouvez également déboguer et émettre des commandes IPython régulières.
Il semble cependant que l'étape ne fonctionne pas (encore?) Bien (c'est-à-dire s'arrêter sur une ligne et ensuite entrer dans une autre fonction) à moins que vous ne définissiez un autre point d'arrêt.
Pourtant, venant de MATLAB, cela semble la meilleure solution que j'ai trouvée.
la source
Depuis python 3.2, vous avez la
interact
commande, qui vous donne accès à tout l'espace de commande python / ipython.la source
L'exécution depuis l'intérieur du shell IPython d'Emacs et le jeu de points d'arrêt via pdb.set_trace () devraient fonctionner.
Vérifié avec python-mode.el, Mx ipython RET etc.
la source
Développer un nouveau code
Débogage dans IPython
Exemple de cellule:
Débogage du code existant
IPython dans le débogage
pytest ... --pdbcls=IPython.terminal.debugger:TerminalPdb --pdb
breakpoint()
,python -m ipdb
, etc.Réflexions sur Python
Je suis d'accord avec l'OP pour dire que beaucoup de choses que MATLAB fait bien Python n'a toujours pas et devrait vraiment le faire puisque à peu près tout dans le langage favorise la vitesse de développement par rapport à la vitesse de production. Peut-être qu'un jour je contribuerai plus que des corrections de bogues triviales à CPython.
https://github.com/ipython/ipython/commit/f042f3fea7560afcb518a1940daa46a72fbcfa68
Voir aussi Est-il possible d'exécuter des commandes dans IPython avec le débogage?
la source