Conseils de débogage Python [fermé]

164

Quels sont vos meilleurs conseils pour déboguer Python?

Veuillez ne pas simplement lister un débogueur particulier sans dire ce qu'il peut réellement faire.

en relation

inconnus
la source

Réponses:

139

PDB

Vous pouvez utiliser le module pdb, insérer pdb.set_trace()n'importe où et il fonctionnera comme un point d'arrêt.

>>> import pdb
>>> a="a string"
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None
(Pdb) p a
'a string'
(Pdb)

Pour continuer l'exécution, utilisez c(ou contou continue).

Il est possible d'exécuter des expressions Python arbitraires en utilisant pdb. Par exemple, si vous trouvez une erreur, vous pouvez corriger le code, puis tapez une expression de type pour avoir le même effet dans le code en cours d'exécution

ipdb est une version de pdb pour IPython . Il permet l'utilisation de pdb avec toutes les fonctionnalités IPython, y compris la complétion des onglets.

Il est également possible de configurer pdb pour qu'il s'exécute automatiquement sur une exception non interceptée.

Pydb a été écrit pour être une version améliorée de Pdb. Avantages?

ghostdog74
la source
Voici un article sur l'utilisation de pdb
sontek
Personnellement, j'aime mieux ipdb .
Sardathrion - contre les abus SE
1
Apparemment, il y a une réécriture de pydb appelée pydbgr
Ehtesh Choudhury
SublimeText a un excellent plugin pour ajouter des points d'arrêt python au code: sublime.wbond.net/packages/Python%20Breakpoints
Dennis Golomazov
Si vous développez une application Web, ajoutez une vue pour myserver.com/pdben mode débogage qui fait simplement import pdb; pdb.set_trace(). Si vous utilisez Flask / Werkzeug qui a un débogueur interactif, vous pouvez également avoir une vue qui fait juste assert False.
osa
78

http://pypi.python.org/pypi/pudb , un débogueur Python plein écran basé sur une console.

Son objectif est de fournir toutes les subtilités des débogueurs modernes basés sur une interface graphique dans un package plus léger et plus convivial pour le clavier. PuDB vous permet de déboguer le code là où vous l'écrivez et le testez - dans un terminal. Si vous avez travaillé avec les excellents (mais de nos jours anciens) outils Turbo Pascal ou C basés sur DOS, l'interface utilisateur de PuDB peut vous sembler familière.

capture d'écran de pudb

Bien pour le débogage de scripts autonomes, exécutez simplement

python -m pudb.run my-script.py
Miku
la source
Installer avecpip install pudb
congusbongus
40

Si vous utilisez pdb, vous pouvez définir des alias pour les raccourcis. J'utilise ceux-ci:

# Ned's .pdbrc

# Print a dictionary, sorted. %1 is the dict, %2 is the prefix for the names.
alias p_ for k in sorted(%1.keys()): print "%s%-15s= %-80.80s" % ("%2",k,repr(%1[k]))

# Print the instance variables of a thing.
alias pi p_ %1.__dict__ %1.

# Print the instance variables of self.
alias ps pi self

# Print the locals.
alias pl p_ locals() local:

# Next and list, and step and list.
alias nl n;;l
alias sl s;;l

# Short cuts for walking up and down the stack
alias uu u;;u
alias uuu u;;u;;u
alias uuuu u;;u;;u;;u
alias uuuuu u;;u;;u;;u;;u
alias dd d;;d
alias ddd d;;d;;d
alias dddd d;;d;;d;;d
alias ddddd d;;d;;d;;d;;d
Ned Batchelder
la source
Comment définissez-vous ces alias?
Casebash
9
Mettez ce truc dans ~ / .pdbrc
Ned Batchelder
sous windows, vous pouvez le mettre dans ~ / _ipython / ipythonrc.ini
fastmultiplication
33

Enregistrement

Python a déjà un excellent module de journalisation intégré . Vous pouvez utiliser le modèle de journalisation ici .

Le module de journalisation vous permet de spécifier un niveau d'importance; pendant le débogage, vous pouvez tout consigner, tandis que pendant le fonctionnement normal, vous ne pouvez consigner que les éléments critiques. Vous pouvez éteindre et rallumer les choses.

La plupart des gens utilisent simplement des instructions d'impression de base pour déboguer, puis suppriment les instructions d'impression. Il est préférable de les laisser, mais de les désactiver; puis, lorsque vous avez un autre bogue, vous pouvez simplement tout réactiver et consulter vos journaux.

Cela peut être le meilleur moyen possible de déboguer les programmes qui doivent faire les choses rapidement, tels que les programmes de mise en réseau qui doivent répondre avant que l'autre extrémité de la connexion réseau expire et disparaisse. Vous n'aurez peut-être pas beaucoup de temps pour un débogueur en une seule étape; mais vous pouvez simplement laisser votre code s'exécuter, tout consigner, puis parcourir les journaux et comprendre ce qui se passe réellement.

EDIT: L'URL d'origine des modèles était: http://aymanh.com/python-debugging-techniques

Cette page est manquante, je l'ai donc remplacée par une référence à l'instantané enregistré sur archive.org: http://web.archive.org/web/20120819135307/http://aymanh.com/python-debugging-techniques

Au cas où il disparaîtrait à nouveau, voici les modèles que j'ai mentionnés. C'est du code tiré du blog; Je ne l'ai pas écrit.

import logging
import optparse

LOGGING_LEVELS = {'critical': logging.CRITICAL,
                  'error': logging.ERROR,
                  'warning': logging.WARNING,
                  'info': logging.INFO,
                  'debug': logging.DEBUG}

def main():
  parser = optparse.OptionParser()
  parser.add_option('-l', '--logging-level', help='Logging level')
  parser.add_option('-f', '--logging-file', help='Logging file name')
  (options, args) = parser.parse_args()
  logging_level = LOGGING_LEVELS.get(options.logging_level, logging.NOTSET)
  logging.basicConfig(level=logging_level, filename=options.logging_file,
                      format='%(asctime)s %(levelname)s: %(message)s',
                      datefmt='%Y-%m-%d %H:%M:%S')

  # Your program goes here.
  # You can access command-line arguments using the args variable.

if __name__ == '__main__':
  main()

Et voici son explication sur la façon d'utiliser ce qui précède. Encore une fois, je n'en ai pas le mérite:


Par défaut, le module de journalisation imprime les messages critiques, d'erreur et d'avertissement. Pour changer cela afin que tous les niveaux soient imprimés, utilisez:

$ ./your-program.py --logging=debug

Pour envoyer des messages de journal à un fichier appelé debug.log, utilisez:

$ ./your-program.py --logging-level=debug --logging-file=debug.log

steveha
la source
1
Le problème avec le module de journalisation est qu'il rompt fortement avec Unicode et diverses solutions de contournement sont nécessaires pour le faire fonctionner dans des applications internationalisées. Cependant, c'est toujours la meilleure solution de journalisation pour Python.
Jacek Konieczny
Le lien «modèle de journalisation ici» est mort. Veuillez mettre à jour.
Yohann
20

Il est possible d'imprimer quelles lignes Python sont exécutées (merci Geo!). Cela a n'importe quel nombre d'applications, par exemple, vous pouvez le modifier pour vérifier quand des fonctions particulières sont appelées ou ajouter quelque chose comme ## pour ne suivre que des lignes particulières.

code.interact vous emmène dans une console interactive

import code; code.interact(local=locals())

Si vous voulez pouvoir accéder facilement à l'historique de votre console, regardez: " Puis-je avoir un mécanisme d'historique comme dans le shell? " (Il faudra le chercher).

La saisie semi-automatique peut être activée pour l' interpréteur .

Casebash
la source
19

ipdb est comme pdb, avec la génialité d'ipython.

Alex Gaynor
la source
5
Pourriez-vous ajouter plus de détails sur ce qu'il peut faire?
Casebash
17

print déclarations

  • Certaines personnes recommandent une debug_printfonction au lieu d'imprimer pour une désactivation facile
  • Le pprintmodule est inestimable pour les structures complexes
hasen j
la source
3
+1 quand chaque débogueur échoue, print est votre ami, oui debug_print serait un ajout intéressant
Anurag Uniyal
J'imprime généralement d'abord puis débogage ensuite sauf quand je sais que je serai capable de résoudre en traçant une section particulière
Casebash
4
En fait, le module de journalisation fait exactement cela.
e-satis
C'est vrai, mais la journalisation doit être configurée. J'apprendrai à utiliser le module après les honneurs
Casebash
print peut être utile pour des cas simples et en particulier lors du développement de projets avec un temps de démarrage réduit. De l'autre côté, cela peut créer une dépendance et son utilisation sur pdb ou tout autre débogueur dans des scénarios plus complexes vous causera généralement des maux de tête
vinilios
16

la manière évidente de déboguer un script

python -m pdb script.py
  • utile lorsque ce script lève une exception
  • utile lorsque vous utilisez virtualenv et que la commande pdb ne fonctionne pas avec la version venvs python.

si vous ne savez pas exactement où se trouve ce script

python -m pdb ``which <python-script-name>``
vinilios
la source
15

PyDev

PyDev a un très bon débogueur interactif. Il contient des expressions de surveillance, un survol pour évaluer, des listes de threads et de piles et (presque) toutes les commodités habituelles que vous attendez d'un débogueur visuel moderne. Vous pouvez même vous attacher à un processus en cours d'exécution et effectuer un débogage à distance.

Comme d'autres débogueurs visuels, cependant, je le trouve utile surtout pour des problèmes simples, ou pour des problèmes très compliqués après avoir tout essayé. Je fais encore la plupart des gros travaux de journalisation.

itsadok
la source
A-t-il la capacité de modifier et de continuer?
Casebash
@CaseBash non, mais cette fonctionnalité est prévue. Même sans cela, la vitesse et la facilité de définition / désactivation des points d'arrêt et de recherche des valeurs variables sont toujours très utiles
Jiaaro
12

Winpdb est très sympa, et contrairement à son nom, il est complètement multiplateforme.

Il a un très bon débogueur basé sur une invite et une interface graphique, et prend en charge le débogage à distance.

orip
la source
@Casebash - ajouté plus de détails
orip
1
+1 C'est le seul débogueur python que j'ai trouvé jusqu'à présent qui puisse gérer le multi-threading.
Lee Netherton
Soyez prudent avec sa "gestion" du multi-threading - toute exception dans n'importe quel thread provoque le blocage de l'ensemble du processus. Pas une mauvaise chose si vous en êtes conscient, très douloureux si vous ne l'êtes pas
Walt W
Le projet semble mort en avril 2014
Alojz Janez
7

Dans Vim, j'ai ces trois liaisons:

map <F9> Oimport rpdb2; rpdb2.start_embedded_debugger("asdf") #BREAK<esc>
map <F8> Ofrom nose.tools import set_trace; set_trace() #BREAK<esc>
map <F7> Oimport traceback, sys; traceback.print_exception(*sys.exc_info()) #TRACEBACK<esc>

rpdb2est un débogueur Python distant, qui peut être utilisé avec WinPDB, un débogueur graphique solide. Parce que je sais que vous allez demander, il peut faire tout ce que j'attends d'un débogueur graphique :)

J'utilise pdbfrom nose.toolsafin de pouvoir déboguer les tests unitaires ainsi que le code normal.

Enfin, le F7mappage imprimera un suivi (similaire au type que vous obtenez lorsqu'une exception apparaît en haut de la pile). Je l'ai trouvé très utile plus de quelques fois.

David Wolever
la source
4

Définir des méthodes utiles repr () pour vos classes (afin que vous puissiez voir ce qu'est un objet) et utiliser repr () ou "% r"% (...) ou "... {0! R} ..". Format (...) dans vos messages / journaux de débogage est IMHO une clé pour un débogage efficace.

De plus, les débogueurs mentionnés dans d'autres réponses utiliseront les méthodes repr ().

Jacek Konieczny
la source
2

Obtenir une trace de pile à partir d'une application Python en cours d'exécution

Il y a plusieurs astuces ici . Ceux-ci inclus

  • Pénétrer dans un interpréteur / imprimer une trace de pile en envoyant un signal
  • Obtenir une trace de pile à partir d'un processus Python non préparé
  • Exécution de l'interpréteur avec des indicateurs pour le rendre utile pour le débogage
Casebash
la source
2

Si vous n'aimez pas passer du temps dans les débogueurs (et n'appréciez pas la mauvaise utilisation de l' pdbinterface de ligne de commande), vous pouvez vider la trace d' exécution et l'analyser plus tard. Par exemple:

python -m trace -t setup.py install > execution.log

Cela videra toute la ligne d' setup.py installexécution source dans execution.log.

Pour faciliter la personnalisation de la sortie de trace et écrire vos propres traceurs, j'ai rassemblé quelques morceaux de code dans le module xtrace (domaine public).

anatoly techtonik
la source
1

Lorsque cela est possible, je débogue en utilisant M-x pdbdans emacs pour le débogage au niveau source.

themis
la source
1

Il existe un cours en ligne complet appelé " Débogage de logiciels " par Andreas Zeller sur Udacity, contenant des conseils sur le débogage:

Résumé du cours

Dans ce cours, vous apprendrez à déboguer systématiquement des programmes, à automatiser le processus de débogage et à créer plusieurs outils de débogage automatisés en Python.

Pourquoi suivre ce cours?

À la fin de ce cours, vous aurez une solide compréhension du débogage systématique, saurez automatiser le débogage et aurez construit plusieurs outils de débogage fonctionnels en Python.

Prérequis et exigences

Une connaissance de base de la programmation et de Python au niveau d'Udacity CS101 ou supérieur est requise. Une compréhension de base de la programmation orientée objet est utile.

Hautement recommandé.

Udi
la source
0

si vous voulez une belle façon graphique d'imprimer votre pile d'appels de manière lisible, consultez cet utilitaire: https://github.com/joerick/pyinstrument

Exécuter à partir de la ligne de commande:

python -m pyinstrument myscript.py [args...]

Exécuter en tant que module:

from pyinstrument import Profiler

profiler = Profiler()
profiler.start()

# code you want to profile

profiler.stop()
print(profiler.output_text(unicode=True, color=True))

Exécutez avec django:

Ajoutez simplement pyinstrument.middleware.ProfilerMiddlewareà MIDDLEWARE_CLASSES, puis ajoutez ?profileà la fin de l'URL de demande pour activer le profileur.

Clapier
la source