Maison >développement back-end >Tutoriel Python >Résumé de l'utilisation de l'outil de débogage Python pdb (Python Debugger)

Résumé de l'utilisation de l'outil de débogage Python pdb (Python Debugger)

WBOY
WBOYavant
2022-11-07 16:46:036347parcourir

Cet article vous apporte des connaissances pertinentes sur Python Il présente principalement le contenu pertinent sur l'outil de débogage pdb, y compris les commandes pdb de base, la définition de points d'arrêt avec break, etc.

Résumé de l'utilisation de l'outil de débogage Python pdb (Python Debugger)

【Recommandation associée : Tutoriel vidéo Python3

1. Il existe 2 façons d'utiliser pdb

pdb : débogueur python

1. de plus, dans la ligne de commande, vous pouvez déboguer en l'exécutant directement sous python3 -m pdb filename.py pdb.set_trace()

Lorsque vous voyez l'invite suivante sur la ligne de commande, cela signifie que pdb a été ouvert correctement

(Pdb)

2. Commandes de base pdb

Command

Explication

break ou bset breakpointcontinue l'exécution du programme
continue ou c
liste ou l afficher le segment de code de la ligne en cours
étape ou s Entrez la fonction (utilisez next au lieu de step pour entrer dans la boucle for)
return ou r exécutez le code jusqu'au retour de la fonction actuelle
next ou n exécutez la ligne suivante
up ou u Retour au dernier point d'appel (pas à la ligne précédente)
p x Imprimer la valeur de la variable

En utilisation réelle, nous avons constaté que lors de l'exécution d'un fichier python avec un script shell, il peut ne pas être possible de déboguer à l'aide de pdb et il se fermera. Pour le moment, vous ne pouvez exécuter le fichier py que directement pour le débogage.

3. Utilisez la commande break pour définir un point d'arrêt à l'emplacement spécifié dans le fichier spécifié

3.1 Définissez un point d'arrêt à l'emplacement spécifié dans ce fichier

Par exemple, dans l'exemple suivant, si vous le souhaitez pour saisir le forward() du modèle Pour visualiser le processus de traitement des données lors de la propagation vers l'avant dans la méthode, vous ne pouvez définir un point d'arrêt que sur la première ligne de forward() (c'est-à-dire la ligne 26), pdb.set_trace()

Mais parfois le modèle est très complexe, utilisez cette méthode. Cela fera que le programme signalera une erreur et se terminera directement (je ne connais pas la raison), alors nous pouvons envisager d'utiliser la commande break pour insérer un point d'arrêt dans cette ligne, afin que le programme s'arrêtera lorsqu'il atteindra forward().

import torchimport torch.nn as nnimport pdbclass EncoderLayer(nn.Module):    def __init__(self):        super().__init__()
        self.conv1 = nn.Conv2d(4, 10, (3, 3))
        self.conv2 = nn.Conv2d(10, 4, (3, 3))
        self.relu = nn.ReLU()    def forward(self, x):
        x=self.relu(self.conv1(x))        return self.relu(self.conv2(x))class Encoder(nn.Module):    def __init__(self,num_layers):        super().__init__()        # encoders 由 num_layers个 EncoderLayer子层组成,每个子层结构相同,但参数不一定相同。
        self.ModelList = nn.ModuleList([EncoderLayer() for _ in range(num_layers)])    def forward(self, x):        # ModuleList是一个list,只能通过list的操作方式(如用for循环、下标索引等)进行forward计算。
        for layer in self.ModelList:
            x = layer(x)        return xif __name__=="__main__":
    pdb.set_trace()   
    input = torch.rand(5, 4, 30, 30)
    model = Encoder(num_layers=4)
    output = model(input)

Méthode spécifique : (1) Définissez d’abord pdb.set_trace() sur n’importe quelle ligne précédente pour arrêter le programme. (2) Entrez simplement le break 26. Comme le montre l'image :

Résumé de lutilisation de loutil de débogage Python pdb (Python Debugger)De cette façon, le point d'arrêt est défini avec succès et le programme s'arrêtera lorsqu'il atteindra forward().

Le 26 ici est le nombre de lignes. Il est à noter que la position du point d'arrêt ne peut pas être un commentaire Par exemple, si nous définissons un point d'arrêt sur la ligne 25 (ligne de commentaire), cela échouera :

Résumé de lutilisation de loutil de débogage Python pdb (Python Debugger)To. résumer, dans le même fichier La commande pour définir un point d'arrêt est la suivante :

ligne de rupture

3.2 Définir des points d'arrêt à des emplacements spécifiés dans d'autres fichiers

Si le point d'arrêt que vous souhaitez définir n'est pas lors de l'exécution initiale fichier, comment pouvez-vous le définir dans d'autres fichiers ? Comment utiliser la commande break pour définir un point d'arrêt ? Regardons cet exemple :

Divisez le code 3.1 en trois fichiers py et placez-les dans le même chemin :

  ![Résumé de lutilisation de loutil de débogage Python pdb (Python Debugger)](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4b5d476ba5b14b0ba541d78930b9704a~tplv-k3u1fbpfcp-zoom-1.image)

Regardez le contenu de chaque fichier :

run.py:

Initial pdb.set_trace( ) est défini dans run.py.

import torchfrom encoder import Encoderimport pdbif __name__=="__main__":
    pdb.set_trace()    input = torch.rand(5, 4, 30, 30)
    model = Encoder(num_layers=4)
    output = model(input)

encoder.py:

from encoder_layer import EncoderLayerimport torch.nn as nnclass Encoder(nn.Module):    def __init__(self,num_layers):        super().__init__()        # encoders 由 num_layers个 EncoderLayer子层组成,每个子层结构相同,但参数不一定相同。
        self.ModelList = nn.ModuleList([EncoderLayer() for _ in range(num_layers)])    def forward(self, x):        # ModuleList是一个list,只能通过list的操作方式(如用for循环、下标索引等)进行forward计算。
        for layer in self.ModelList:
            x = layer(x)        return x

encoder_layer.py:

import torch.nn as nnclass EncoderLayer(nn.Module):    def __init__(self):        super().__init__()
        self.conv1 = nn.Conv2d(4, 10, (3, 3))
        self.conv2 = nn.Conv2d(10, 4, (3, 3))
        self.relu = nn.ReLU()    def forward(self, x):
        x=self.relu(self.conv1(x))        return self.relu(self.conv2(x))

Maintenant, nous exécutons run.py et définissons un point d'arrêt sur la ligne 12 de encoder.py, qui est

for layer in self. :

La commande est :

break encoder.py:12

c'est-à-dire break filename: lineRésumé de lutilisation de loutil de débogage Python pdb (Python Debugger)Nous pouvons voir que le programme peut entrer forward() à partir de output = model(input):Résumé de lutilisation de loutil de débogage Python pdb (Python Debugger)Cela fonctionne Très facile à déboguer.

Si le point d'arrêt initial et le point d'arrêt cible ne se trouvent pas dans le fichier dans le même répertoire, vous pouvez également définir le point d'arrêt via le nom du fichier sous le chemin relatif, par exemple :

(Pdb) break ../transformer/asr_model.py:91Breakpoint 1 at /local/wenet/examples/aishell/s0/wenet/transformer/asr_model.py:91(Pdb)

4 Problèmes détectés lors de l'utilisation de pdb

. 4.1 Lors de l'utilisation de liens symboliques, le chemin du fichier affiché par pdb n'est pas cohérent avec le chemin réel. Comme le montre la figure, pdb se compose de trois lignes. La première ligne est le chemin du fichier, la deuxième ligne est la ligne de code actuellement exécutée. , et la troisième ligne est la ligne de commande d'entrée. Lorsqu'il y a un lien symbolique, le chemin affiché par pdb est le chemin pointé par le lien symbolique, mais le chemin du code réel est le chemin qui copie le contenu du lien symbolique. Ces deux chemins sont différents, alors assurez-vous de le faire. Faites attention.

Résumé de lutilisation de loutil de débogage Python pdb (Python Debugger)4.2 pdb ne peut parfois pas ajouter de points d'arrêt dans la méthode forward() du modèle

pdb ne peut parfois pas utiliser pdb.set_trace() pour ajouter des points d'arrêt dans la méthode forward() du modèle. : :

Les fonctions compilées ne peuvent pas prendre un nombre variable d'arguments ou utiliser des arguments de mots-clés uniquement avec les paramètres par défaut

Cela signifie probablement "Les fonctions compilées ne peuvent pas prendre un nombre variable d'arguments ou utiliser des arguments de mots-clés uniquement avec les paramètres par défaut". ”

Je ne comprends pas ce que cela signifie et ce problème n'a pas été résolu.

5. Post-débogage après le crash du programme : pdb.pm()

Comme mentionné ci-dessus, les points d'arrêt sont insérés lorsque le programme démarre et pdb est utilisé pour le débogage, c'est-à-dire le

pré-débogage

. En fait, pdb peut également être utilisé pour le débogage post-mortem, c'est-à-dire qu'après un bug et un crash du programme, utilisez le débogueur python pour l'afficher.

Par exemple, test.py a évidemment un bug :

# test.pydef add(n):    return n+1add("hello")
Exécutez-le directement :

python test.py

Le programme plante :

F:\PycharmProjects\pytorch_practice>python test.py
Traceback (most recent call last):
  File "test.py", line 4, in <module>
    add("hello")
  File "test.py", line 2, in add
    return n+1
TypeError: can only concatenate str (not "int") to str</module>
De cette façon, nous ne pouvons pas utiliser pdb pour le débogage. Alors, lorsque le programme plante, comment devons-nous le déboguer ?

Nous pouvons utiliser la commande suivante pour un débogage simple :

python -i test.py

L'option -i vous permet d'ouvrir un shell interactif une fois le programme terminé, comme suit :

F:\PycharmProjects\pytorch_practice>python -i test.py
Traceback (most recent call last):
  File "test.py", line 4, in <module>
    add("hello")
  File "test.py", line 2, in add
    return n+1
TypeError: can only concatenate str (not "int") to str
>>></module>

现在我们发现程序结束后出现了 >>> 符号,这就是python调试器。

输入命令:

import pdb pdb.pm()

其中 pdb.pm() 用于程序发生异常导致奔溃后的事后调试,可以跟踪异常程序最后的堆在信息。

执行命令后得到:

TypeError: can only concatenate str (not "int") to str
>>> import pdb
>>> pdb.pm()
> f:\pycharmprojects\pytorch_practice\test.py(2)add()
-> return n+1
(Pdb)

可以发现,pdb.pm() 已经追踪到了导致程序奔溃的语句:return n+1

此时可以打印 n 的值进行检查:

(Pdb) p n'hello'(Pdb) q>>> quit()

F:\PycharmProjects\pytorch_practice>

q 表示退出pdb调试,quit() 表示退出 python 调试器。

【相关推荐:Python3视频教程

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer