web-dev-qa-db-fra.com

Python astuces de débogage

Quels sont vos meilleurs conseils pour déboguer Python?

S'il vous plaît, ne vous contentez pas de lister un débogueur particulier sans dire ce qu'il peut réellement faire.

Apparenté, relié, connexe

164
Casebash

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 cont ou continue).

Il est possible d'exécuter des expressions Python arbitraires à l'aide de 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 par tabulation.

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?

139
ghostdog74

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

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

pudb screenshot

Idéal pour le débogage de scripts autonomes, il suffit de lancer

python -m pudb.run my-script.py
78
miku

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

# 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
40
Ned Batchelder

Journalisation

Python a déjà un excellent module de journalisation intégré . Vous voudrez peut-être 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 enregistrer, tandis qu'en fonctionnement normal, vous ne pouvez enregistrer que des choses critiques. Vous pouvez allumer et éteindre les choses.

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

Cela peut constituer le meilleur moyen de déboguer des programmes qui doivent agir rapidement, tels que des programmes réseau devant répondre avant que l’autre extrémité de la connexion réseau n’expire et ne disparaisse. Vous n’avez peut-être pas beaucoup de temps pour déboguer en une seule étape; mais vous pouvez simplement laisser votre code s'exécuter et tout journaliser, 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 alors je l'ai 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 encore, 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 __== '__main__':
  main()

Et voici son explication sur la façon d'utiliser ce qui précède. Encore une fois, je ne reçois pas le crédit pour cela:


Par défaut, le module de journalisation imprime des messages critiques, d'erreur et d'avertissement. Pour changer ceci 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

33
steveha

Il est possible d’imprimer quoi les lignes Python sont exécutées (merci Geo!). Cela a un nombre quelconque d'applications, par exemple, vous pouvez le modifier pour vérifier le moment où des fonctions particulières sont appelées ou ajouter quelque chose comme ## le faire suivre uniquement 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 automatique peut être activée pour le interprète .

20
Casebash

ipdb est comme pdb, avec le génie d'Ipython.

19
Alex Gaynor

print déclarations

  • Certaines personnes recommandent une fonction debug_print au lieu d’imprimer pour la désactiver facilement.
  • Le module pprint est inestimable pour les structures complexes
17
hasen

le moyen évident de déboguer un script

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

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

python -m pdb ``which <python-script-name>``
16
vinilios

PyDev

PyDev a un très bon débogueur interactif. Il contient des expressions de regard, des survols en amont, 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 connecter à un processus en cours et effectuer un débogage à distance.

Cependant, à l'instar d'autres débogueurs visuels, je le trouve utile principalement pour des problèmes simples ou pour des problèmes très compliqués après avoir essayé tout le reste. Je fais toujours l'essentiel du travail lourd avec l'exploitation forestière.

15
itsadok

Si vous connaissez Visual Studio, Outils Python pour Visual Studio est ce que vous recherchez.

enter image description here

15
coordinate

Winpdb est très gentil, et contrairement à son nom, il est complètement multi-plateforme.

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

12
orip

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>

rpdb2 est un débogueur distant Python pouvant être utilisé avec WinPDB, un débogueur graphique plein. Parce que je sais que vous allez demander, il peut faire tout ce que je m'attends d'un débogueur graphique :)

J'utilise pdb à partir de nose.tools pour pouvoir déboguer des tests unitaires ainsi que du code normal.

Enfin, le mappage F7 imprimera une trace (semblable à celle que vous obtenez lorsqu'une exception survient en haut de la pile). Je l'ai trouvé très utile plusieurs fois.

7
David Wolever

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} .. ". Le format (...) dans vos messages/journaux de débogage est, à mon humble avis, un élément clé pour un débogage efficace.

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

4
Jacek Konieczny

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

Il y a plusieurs astuces ici . Ceux-ci inclus

  • Entrer dans un interprète/imprimer une trace de pile en envoyant un signal
  • Obtenir une trace de pile d'un processus Python non préparé
  • Exécution de l'interprète avec des indicateurs pour le rendre utile pour le débogage
2
Casebash

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

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

Cela va vider toute la ligne source de setup.py install exécution en execution.log.

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

2

Il existe un cours en ligne complet intitulé " Débogage logiciel " par Andreas Zeller sur Udacity, qui regorge de conseils sur le débogage:

Résumé du cours

Dans cette classe, vous apprendrez à déboguer des programmes de manière systématique, à automatiser le processus de débogage et à construire plusieurs outils de débogage automatisés en Python.

Pourquoi suivre ce cours?

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

Conditions préalables et exigences

Des connaissances de base en programmation et en Python au niveau de Udacity CS101 ou supérieur sont requises. Compréhension de base de la programmation orientée objet est utile.

Hautement recommandé.

1
Udi

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

1
themis

si vous voulez un moyen graphique agréable d’imprimer votre pile d’appels de manière lisible, consultez cet utilitaire: https://github.com/joerick/pyinstrument

Exécuter en 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))

Courir avec Django:

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

0
Hutch