web-dev-qa-db-fra.com

Comment déboguer efficacement avec spyder en Python?

J'aime Python et Spyder, mais le débogage avec Spyder est terrible!

  • Chaque fois que je mets un point d'arrêt, j'ai besoin d'appuyer sur deux boutons: d'abord Le bouton de mise au point, puis sur le bouton continuer (il se met en pause à la première ligne Automatiquement), ce qui est agaçant. 
  • De plus, plutôt que d’avoir la console standard iPython avec complétion automatique, etc., j’ai une mauvaise console ipdb >> qui ne sert à rien. 
  • Le pire, c’est que cette console se fige très souvent, même si j’écris des impressions ou une simple évaluation pour essayer de comprendre quel est le bogue. C'est bien pire que matlab. 
  • Dernier point mais non le moindre, si j'appelle une fonction depuis la console Ipdb >> et que je mets un point d'arrêt à l'intérieur de celle-ci, elle ne s'arrêtera pas là . le débogage .__ (ctrl + F5).

Avez-vous une solution ou pouvez-vous me dire comment vous déboguez les scripts et les fonctions Python?

J'utilise une nouvelle installation d'Anaconda sur Windows 8.1 64 bits.

54
Hanan Shteingart

( Spyder dev here ) Nous sommes conscients que l'expérience de débogage dans Spyder est loin d'être idéale. Ce que nous proposons actuellement est très similaire au débogueur Python standard, mais nous travaillons à améliorer la prochaine version majeure afin de fournir un résultat plus proche de ce que tout scientifique pourrait attendre d’un débogueur vous inspectez et tracez les variables au point d'arrêt actuel).

Maintenant à propos de vos points:

  1. C'est vrai. Nous pensons améliorer cela de sorte que si l'utilisateur appuie sur le bouton Exécuter et qu'un point d'arrêt est présent dans le fichier actuel, Spyder entre en mode débogage et exécute le programme jusqu'à ce que le premier point d'arrêt soit atteint.

  2. ipdb est la console du débogueur IPython. Malheureusement, en raison de limitations dans l'architecture IPython, il est très limité (pas de complétion de code et pas de navigation dans l'historique avec des flèches). En outre, il n'est pas possible d'exécuter du code Python arbitraire dans la console ipdb ou dans une console pdb standard. Les commandes que vous pouvez exécuter dans ipdb sont celles que vous pouvez lire lorsque vous évaluez la commande help à l'intérieur de celle-ci.

  3. C'est parce que, comme je l'ai dit, vous ne pouvez pas évaluer de code Python arbitraire.

  4. Vous devez insérer de nouveaux points d'arrêt dans notre éditeur afin qu'ils soient synchronisés avec nos consoles Python/IPython.

40
Carlos Cordoba

Flux de travail de débogage

Vous devez comprendre qu'en fait, vous utilisez différentes intégrations des débogueur Python pdbname __ et ipdbNAME _ (qui utilise pdbet accessible via le module ipdbNAME_ ). J'espère que cet exemple trivial vous aidera à mieux l'utiliser.

Supposons que vous souhaitiez déboguer ce code:

def Waiting_fun():                      #1 line number one
    for i in range(100):                #2
        pass                            #3
                                        #4 
def New_sum(lista, to_s = False):       #5
    result = 0                          #6
    print 1                             #7
    for i in lista:                     #8
        print "summed"                  #9   
        result +=i                      #10
    Waiting_fun()                       #11
    if to_s:                            #12
        result = str(result)
    return result
a = New_sum([1,4,5,7,8])
b = New_sum([1,4],1)
c = 456
d = New_sum([6,8,9],1)
final_result = a*b*c*d
Out: Type error

Premier débogage rapide avec iPython% debug

%debug

La première chose que je fais est d’appeler pdb depuis iPython à l’aide de la commande magique %debug, vous pouvez le définir comme mécanisme par défaut à l’aide de %pdb.

%debug
> /home/opdate/Desktop/test.py(23)<module>()
     19 a = New_sum([1,4,5,7,8])
     20 b = New_sum([1,4],1)
     21 c = 456
     22 d = New_sum([6,8,9],1)
---> 23 final_result = a*b*c*d

Une fois que vous avez déjeuné pdbname__. Vous pouvez trouver toutes les commandes dans documents officiels ou vous pouvez utiliser la commande hpour les afficher. Dans cette étape, les seules commandes que j'utilise sont:

  • pname__: affiche les variables que vous spécifiez
  • ppname__: de jolies impressions
  • argsname__: si vous êtes dans une fonction, elle affiche les arguments
  • pp locals(): peut être utile pour imprimer toutes les variables, mais la plupart du temps, c'est la pagaille!
  • ! utilisez-le si vous souhaitez éviter les conflits avec les commandes répertoriées dans hname__
  • whatisnom_variable: équivalent du type (nom_variable)
  • uname__: déplace l'image actuelle d'un niveau vers le haut dans la trace de la pile (vers une image plus ancienne).
  • dname__: déplace l'image actuelle d'un niveau vers le bas dans la trace de la pile (vers une image plus récente).
  • qname__: lorsque vous avez terminé, vous pouvez utiliser q pour quitter

Dans notre cas:

ipdb> pp a,b,c,d
(25, '5', 456, '23')

Ou ipdb> !a,b,c,d (aucun espace entre l'esclamation et la première valeur). Il est clair que b et d sont des chaînes dans le cas où nous pouvons utiliser:

ipdb> whatis b
<type 'str'>

Aller plus loin en utilisant des points d'arrêt

70% des fois %debug vous indique la solution. Lorsque vous avez besoin de plus de fonctionnalités telles que des points d'arrêt , il est temps d'utiliser Spyder. Dans ce cas, nous voulons comprendre pourquoi best une chaîne pour laquelle nous avons placé un point d'arrêt. Je trouve beaucoup mieux d'utiliser la console Python standard au lieu de la console IPython pour le débogage. Sélectionnez donc la console avant de lancer le débogage: enter image description here

Puis ouvrez le variable Explorer s’il existe des variables, supprimez-les. j'utilise Ctrl+F5 pour commencer le débogage, vous pouvez utiliser les boutons en haut mais je préfère utiliser leurs raccourcis illustrés ci-dessous:

enter image description here

(Pdb) c # we go to the breakpoint 
(Pdb) s # we step into the function
(Pdb) args # we see what parameters are inserted
(Pdb) s # going step-by-step
(Pdb) ⏎ # series of Enters go line by line quicker
#Here I'll use  whatis command but in fact I just look to
# the type in variable Explorer of spyder.
(Pdb) whatis result #check if result is still int
(Pdb) unt #or until -useful to exiting from loops see doc.
(Pdb) n # we  don't  enter to the Waiting_fun function
(Pdb) s # going step-by-step
(Pdb) whatis result #we find that there the int is converted
(Pdb) j 6 # for double checking we jump back to 6 were the result is assigned 
# We may be tempted to j(ump) to line 12 but doing so we would skip all the code
#for avoiding a series of `s`,`unt` and `n` we can use this solution:
(Pdb) tbreak 12 #set a new temporary breakpoint. Also `b` it's ok most of the time
(Pdb) c  # go to it 
(Pdb) j 6 # we jump to 6 the code we jump is NOT executed
(Pdb) whatis result# we find that if we jump 12-13 result is still int

Maintenant, nous avons localisé l'erreur. Nous pouvons également tester une solution . Nous répétons l’étape jusqu’à 12 heures et définissons to_s = False

(Pdb) to_s = False #!to_s = False to be on the safe side

Ça marche. Une fonctionnalité importante utilisant la pdb standard dans la console Python est que vous avez une concurrence automatique et que vous pouvez utiliser la variable Explorer au lieu d'utiliser whatiset ppname__:

enter image description here

À l'aide de la variable Explorer, vous pouvez également modifier la valeur des variables, ce qui rend les choses encore plus rapides.

Points d'arrêt conditionnels

Un autre moyen plus intelligent de localiser l'erreur consiste à utiliser un point d'arrêt conditionnel (Shift+F12) L’un des grands avantages de Spyder est de déboguer et d’utiliser les points de contrôle de la liste. Les points d'arrêt conditionnels sont activés lorsque la condition est TrueDans notre cas, nous souhaitons localiser où b devient une chaîne, de sorte que la condition est: type(b) == str. J'ai l'habitude de placer beaucoup de points d'arrêt conditionnels et de voir lequel répond à la condition. Pour ce faire, n'utilisez pas Shift+F12 mais placez des points d'arrêt normaux en double-cliquant à côté de la ligne et accédez à Débogage-> Liste des points d'arrêt, puis copiez et collez la condition dans le tableau pour chaque point d'arrêt, comme indiqué dans la figure ci-dessous.

enter image description here

A partir de là, les commandes à utiliser sont:

(Pdb) c  # go to the first
(Pdb) u # it helps to understand when it happened
(Pdb) d # come back to the breakpoint
20
G M

Le débogueur pdb fonctionne très bien avec regular python. Donc, dans Spyder, je viens de passer à la console Python chaque fois que je veux déboguer de manière interactive. 

import pdb

def yourfunction():
    # Interesting stuff done here
    pdb.set_trace() 

Belle introduction au débogage avec pdb https://pythonconquerstheuniverse.wordpress.com/category/python-debugger/

4
LtGlahn

Voici comment je débogue dans Spyder afin d'éviter de geler l'IDE. Je le fais si je modifie le script en mode de débogage. 

  1. Je ferme la console IPython (débogage) actuelle [x]
  2. Ouvrir un nouveau [Barre de menu-> Consoles-> Ouvrir une console IPython]
  3. Revenez en mode débogage [bouton de pause de lecture bleue]. 

Toujours un peu gênant, mais il présente l’avantage supplémentaire d’effacer la liste de variables 

1
oogieoogieful

Personne n'a jamais mentionné ces deux auparavant, apparemment:

Avant Python, j'utilisais VBA. Bien qu’il s’agisse d’un langage relativement ancien qui n’est pas régulièrement mis à jour, la fonction de débogage me plaisait dans VBA. Les 2 fonctions de débogage les plus proches de VBA ou pouvant être qualifiées de "débogage visuel" que j'ai rencontrées sont:

1-PyCharm Debugger

Cette vidéo 6 minutes illustre le débogueur PyCharm.

2-PixieDebugger - Le débogueur Visual Python pour les blocs-notes Jupyter que vous avez toujours voulu

Étant donné que de nombreux codeurs ont tendance à utiliser JupyterNotebook, ce débogueur serait pratique. PixieDebugger est presque identique au débogueur PyCharm. Je ne vais pas entrer dans les détails ici.

Mais vous pouvez vous référer à ceci link

0
mcagriardic

Un petit extra concernant le point 3:

Il me semblait également que la console de débogage se figeait fréquemment, effectuant des impressions, des évaluations, etc., mais le fait d’appuyer sur le bouton stop (Quitter le débogage) l’a en général renvoyé au bas de la pile d’appel, puis je pouvais remonter («u»). Je suis en train de déboguer le cadre. Ça vaut le coup d'essayer. Cela pourrait être pour une version ultérieure de Spyder (2.3.5.2)

0
Paul

Vous pouvez utiliser les touches de raccourci de débogage telles que: Étape supérieure à F10 Étape inférieure à F11.__inoutils> préférences> raccourcis clavier

0
Mahyar