Domine a Depuração em Python: Técnicas Eficientes e Boas Práticas

Depurar código Python, para muitos de nós, resume-se a adicionar instruções print e tentar raciocinar o que está acontecendo com base na saída. Não é ideal, mas por algum motivo, as pessoas simplesmente não querem tocar no depurador Python.
Usando print para depurar código
Se você é uma daquelas pessoas que usam print para depurar, não estou julgando você. Aprender Python é difícil. Programar é difícil. A vida é difícil. Entendo que aprender mais uma coisa parece cansativo se você já está lutando. E adicionar aquela instrução print ao seu código… é apenas mais fácil. Uma pequena confissão: eu ainda faço isso o tempo todo também. Não é tão ruim quanto alguns fazem parecer.
Dito isso, vou te ensinar um pequeno truque que será tão fácil quanto adicionar instruções print ao seu código. No entanto, este truque lhe dá poderes infinitos de depuração e permitirá que você conquiste o mundo, se precisar.
Definindo um breakpoint no depurador Python
Você não precisa de uma IDE para depurar seu código corretamente. Este truque sempre funciona, mesmo no editor mais simples, e até em Jupyter Notebooks.
O truque resume-se a isto: definir um chamado breakpoint usando a instrução breakpoint(). Você pode inseri-lo no seu código, não importa qual editor ou IDE esteja usando, no ponto onde normalmente colocaria aquela instrução print chata.
Então, o que acontece quando você faz isso? Vamos descobrir! Crie um programa simples, como o abaixo:
def add_two(x):
return x + 2
for i in range(1, 10):
a = add_two(i)
breakpoint()
print(a)
Quando você executa isso, e não importa se faz no REPL, na linha de comando ou na sua IDE, você é jogado no depurador Python chamado PDB. Mas e agora?
Usando o depurador Python
Quando inicio o pequeno programa acima, isto é o que acontece:
$ python3 breakpointing.py
> /home/erik/breakpointing.py(7)<module>() -> print(a)
(Pdb)
Há algumas coisas para ver aqui:
- Mostra o arquivo atual que foi iniciado (
breakpointing.py) - Depois, mostra o próximo comando que estava prestes a rodar, mas foi interrompido pela chamada a
breakpoint(). - E finalmente, vemos o prompt do pdb, esperando nossa entrada.
O depurador Python é na verdade um shell Python totalmente funcional, assim como o REPL.
Neste ponto, podemos inspecionar o ambiente atual. Vamos ver qual o valor de a agora:
(Pdb) print(a)
3
(Pdb) print(i)
1
Em vez de print, você também pode usar o comando específico do pdb p, assim:
(Pdb) p a
3
(Pdb) p i
1
Executando a próxima linha
E se quisermos executar a próxima linha de código? Existem duas opções:
- Com
soustep, você executa a linha atual. O depurador para na primeira ocasião possível depois disso. - Com
nounext, você executa a linha atual também, mas agora o depurador continua até a próxima linha da função atual ser alcançada.
Para tornar isso mais claro: step entra felizmente em uma chamada de função e para dentro dessa função. Em contraste, next executa a função até que ela retorne, e para na próxima linha.
Outros depuradores e IDEs também chamam isso de 'step into' (em vez de step) e 'step over' (em vez de next).
Agora vamos usar estes dois:
$ python3 breakpointing.py
-> print(a)
(Pdb) s
3
-> for i in range(1, 10):
(Pdb) s
-> a = add_two(i)
(Pdb) n
-> breakpoint()
(Pdb) n
-> print(a)
(Pdb) n
4
-> for i in range(1, 10):
(Pdb) s
-> a = add_two(i)
(Pdb) s
--Call--
-> def add_two(x):
(Pdb) s
-> return x + 2
(Pdb) s
--Return--
5
-> return x + 2
(Pdb) s
-> breakpoint()
(Pdb)
Como você pode ver, primeiro passamos por cima da chamada a add_two com n. Na segunda vez, entramos na função com s.
Comandos do depurador Python
Existem mais comandos que você pode testar por conta própria. Não vou listar todos, apenas os mais úteis:
h(help): imprime todos os comandos disponíveis. Também aceita um argumento, ex.h cdiz o que o comandocfazc(continue): começa a rodar até o próximo breakpointl(list): lista o código fonte ao redor da linha atualp: imprime o resultado da expressão seguinte. Você pode usar isso em vez de chamarprint()pp: pretty print, útil para imprimir estruturas de dados como dicionáriosrestart: reinicia o programa atual
Para a documentação completa, acesse a página do depurador Python, onde todos os comandos estão listados.
Continue aprendendo
Embora isso possa ser super útil, vale a pena mergulhar no depurador que sua IDE oferece. Se você é usuário de VSCode, escrevi um tutorial sobre como depurar código Python no VSCode.

python
- Dominando I/O e Importação de Módulos em Python: Guia Prático
- Função Print() do Python: Guia Prático com Exemplos
- Domine Operações com Strings em Python: Replace, Join, Split, Reverse e Conversão de Case
- Python time.sleep(): Como Adicionar Atrasos no Seu Código (Exemplo)
- Print em Python Sem Nova Linha: Dominando o Parâmetro end e Outras Técnicas
- Maximize Lucros com Gestão de Frota Conectada Expandida da Ford
- Acelere a Produção: Como a Prototipagem Aprimora seu Processo de Manufatura
- 5 Estratégias Comprovadas para Elevar a Qualidade de Peças de Chapa Metálica
- 3 Estratégias Comprovadas para Elevar Seu Plano de Manutenção de Equipamentos Industriais
- Domine Design de PCB: Dicas Essenciais e Melhores Práticas para Engenheiros