Python Depuração
Há erros que o Python mostra na hora, com traceback e tudo. E há os piores: o programa roda até o fim, sem reclamar, e dá a resposta errada. O carrinho da lojinha da Ana cobra R$ 19,99 por uma compra de quase cem reais, e nenhuma mensagem diz por quê. Achar a causa de um defeito assim se chama depurar (em inglês, debugging: "tirar os insetos", porque defeito de programa tem o apelido de bug, "inseto"). Nesta aula você vai depurar de dois jeitos: com print e com o depurador do Python, o pdb.
- A ideia da depuração: comparar o que o programa faz com o que você acha que ele faz.
- A depurar com
print, e o atalhof"{variavel=}". - A pausar o programa no meio com
breakpoint()e olhar as variáveis. - Os comandos do
pdb:l,n,s,p,c,q, e tambémw,b,lleh. - A rodar um programa inteiro dentro do depurador com
python3 -m pdb, e a examinar o programa logo depois de um erro. - Os enganos comuns: variável que ainda não existe, variável com nome de comando,
breakpoint()esquecido no código.
A ideia: assistir ao programa em câmera lenta
Pense numa receita de bolo que deu errado: o bolo saiu salgado. Ler a receita de novo não ajuda, porque você acha que seguiu tudo certinho. O que ajuda é refazer a receita olhando cada passo: "pus o açúcar… espera, esse pote é o do sal!". O defeito está no ponto em que o que aconteceu deixa de bater com o que você esperava.
Depurar é isso. Você escolhe um ponto do programa, olha o valor das variáveis ali, e compara com o que esperava. Se bate, o defeito está mais adiante; se não bate, está antes. Há duas lupas para olhar:
| Lupa | Como funciona | Parece com… |
|---|---|---|
print | Você põe prints no código e roda de novo. Eles mostram os valores enquanto o programa passa | Deixar bilhetes pelo caminho |
pdb / breakpoint() | O programa para num ponto, e você pergunta o que quiser, avança uma linha por vez, segue | Pausar o filme e andar quadro a quadro |
1. O programa com defeito
A função soma o carrinho e cobra R$ 15 de frete, que fica de graça acima de R$ 100:
def total_com_frete(itens, frete):
total = 0
for preco, quantidade in itens:
subtotal = preco * quantidade
total = subtotal
if total > 100:
frete = 0
return total + frete
carrinho = [(27.90, 2), (8.49, 3), (4.99, 1)]
print(f"Total: R$ {total_com_frete(carrinho, 15):.2f}")
$ python3 carrinho.py Total: R$ 19.99
Faça a conta de cabeça: 2 arroz a 27,90 dão 55,80; 3 feijão a 8,49 dão 25,47; 1 açúcar, 4,99. Os produtos somam 86,26; com o frete, 101,26. O programa disse 19,99. Nenhum erro, nenhum traceback. Onde está o problema? (Se você já viu, ótimo; finja que não, e acompanhe o método, que vale para os defeitos que não se veem a olho.)
2. Depurando com print
A primeira lupa: um print dentro do laço, mostrando tudo o que muda a cada volta. Costuma-se começar a linha com algo como DEBUG:, para distinguir da saída normal (e lembrar de apagar depois):
def total_com_frete(itens, frete):
total = 0
for preco, quantidade in itens:
subtotal = preco * quantidade
total = subtotal
print("DEBUG:", preco, quantidade, subtotal, total)
if total > 100:
frete = 0
return total + frete
carrinho = [(27.90, 2), (8.49, 3), (4.99, 1)]
print(f"Total: R$ {total_com_frete(carrinho, 15):.2f}")
$ python3 carrinho_print.py DEBUG: 27.9 2 55.8 55.8 DEBUG: 8.49 3 25.47 25.47 DEBUG: 4.99 1 4.99 4.99 Total: R$ 19.99
Leia as três linhas comparando com o esperado. Na primeira volta, total é 55,8: certo. Na segunda, devia ser 55,8 + 25,47 = 81,27, mas é 25,47, igual ao subtotal. Achou: o total não está acumulando, está sendo trocado a cada volta. No fim ele vale só o último item (4,99), e 4,99 + 15 = 19,99.
O atalho = das f-strings
Com quatro números soltos, é fácil esquecer qual é qual. Nas f-strings, um = depois do nome da variável mostra o nome e o valor:
print(f"{subtotal=} {total=}")
$ python3 carrinho_igual.py subtotal=55.8 total=55.8 subtotal=25.47 total=25.47 subtotal=4.99 total=4.99 Total: R$ 19.99
f"{total=}" vira total=55.8. Funciona com qualquer expressão: f"{preco * quantidade=}" mostra preco * quantidade=55.8.
Missão: conserte o carrinho. Se quiser, ponha antes um print(f"{total=}") dentro do laço para ver o defeito acontecer; depois corrija a linha do total para que ele acumule os subtotais (e apague o print de depuração). O total certo é R$ 101.26.
def total_com_frete(itens, frete):
total = 0
for preco, quantidade in itens:
subtotal = preco * quantidade
total = subtotal
if total > 100:
frete = 0
return total + frete
carrinho = [(27.90, 2), (8.49, 3), (4.99, 1)]
print(f"Total: R$ {total_com_frete(carrinho, 15):.2f}")
def total_com_frete(itens, frete):
total = 0
for preco, quantidade in itens:
subtotal = preco * quantidade
total += subtotal
if total > 100:
frete = 0
return total + frete
carrinho = [(27.90, 2), (8.49, 3), (4.99, 1)]
print(f"Total: R$ {total_com_frete(carrinho, 15):.2f}")
print é a melhor lupa
O print é rápido, funciona em qualquer lugar e mostra a história inteira de uma vez (todas as voltas do laço). O ponto fraco: a cada pergunta nova ("e o preco?"), você edita e roda de novo, e no fim precisa apagar todos os prints. Em programas que vão continuar rodando por muito tempo, o lugar dos bilhetes é o logging, que pode ser ligado e desligado sem apagar nada.
3. Pausando o programa: breakpoint()
A segunda lupa. A função embutida breakpoint() ("ponto de parada") faz o programa parar naquela linha e abrir o pdb, o depurador do Python (Python debugger). Ali você pode perguntar o valor de qualquer variável, executar uma linha por vez e, quando quiser, deixar o programa seguir.
def total_com_frete(itens, frete):
total = 0
for preco, quantidade in itens:
breakpoint()
subtotal = preco * quantidade
total = subtotal
if total > 100:
frete = 0
return total + frete
carrinho = [(27.90, 2), (8.49, 3), (4.99, 1)]
print(f"Total: R$ {total_com_frete(carrinho, 15):.2f}")
Abaixo, a sessão de verdade, no terminal da Ana. Depois de cada (Pdb), o que ela digitou; o resto é a resposta do Python. Ela vai olhar a primeira volta do laço, deixar o programa seguir até a segunda e conferir o total:
$ python3 carrinho_bp.py > /home/ana/carrinho_bp.py(4)total_com_frete() -> breakpoint() (Pdb) l 1 def total_com_frete(itens, frete): 2 total = 0 3 for preco, quantidade in itens: 4 -> breakpoint() 5 subtotal = preco * quantidade 6 total = subtotal 7 if total > 100: 8 frete = 0 9 return total + frete 10 11 (Pdb) p preco, quantidade (27.9, 2) (Pdb) n > /home/ana/carrinho_bp.py(5)total_com_frete() -> subtotal = preco * quantidade (Pdb) n > /home/ana/carrinho_bp.py(6)total_com_frete() -> total = subtotal (Pdb) p subtotal, total (55.8, 0) (Pdb) n > /home/ana/carrinho_bp.py(3)total_com_frete() -> for preco, quantidade in itens: (Pdb) p total 55.8 (Pdb) c > /home/ana/carrinho_bp.py(4)total_com_frete() -> breakpoint() (Pdb) p preco, quantidade, total (8.49, 3, 55.8) (Pdb) n > /home/ana/carrinho_bp.py(5)total_com_frete() -> subtotal = preco * quantidade (Pdb) n > /home/ana/carrinho_bp.py(6)total_com_frete() -> total = subtotal (Pdb) n > /home/ana/carrinho_bp.py(3)total_com_frete() -> for preco, quantidade in itens: (Pdb) p total 25.47 (Pdb) q Quitting pdb will kill the process. Quit anyway? [y/n] y
Vamos por partes:
- > /home/ana/carrinho_bp.py(4)total_com_frete()
- Onde o programa está parado: arquivo, linha 4, dentro da função
total_com_frete. - -> breakpoint()
- A próxima linha a ser executada (ela ainda não rodou).
- (Pdb)
- O "prompt" do depurador: ele espera um comando seu, como o
>>>do modo interativo. - l
- list, "listar": mostra o código em volta, com uma setinha
->na linha atual. - p preco, quantidade
- print, "mostrar": calcula e mostra o valor. Primeira volta: 27,9 e 2.
- n
- next, "próxima": executa a linha atual e para na seguinte. Dois
ne a Ana está na linha 6, com osubtotaljá calculado (55,8) e ototalainda 0. - c
- continue, "continuar": deixa o programa correr até a próxima parada. Como o
breakpoint()está dentro do laço, ele para de novo na segunda volta. - p total → 25.47
- O momento "achei!": no começo da segunda volta, o
totalera 55,8; depois da linha 6, virou 25,47 em vez de 81,27. A linha 6 troca o valor em vez de somar. - q
- quit, "sair": encerra o depurador e o programa. No Python 3.14, quando o
pdbfoi aberto por umbreakpoint(), ele pede confirmação:Quit anyway? [y/n]("Sair do pdb vai matar o processo. Sair mesmo assim?"). A Ana respondeuy(yes, "sim";né no, "não") 3.14.
No (Pdb), você pode digitar o nome de uma variável sozinho (total) e ele mostra o valor, ou até uma conta (preco * quantidade). O p é necessário quando o nome da variável é igual ao de um comando; veja em Quando dá errado. E você pode mudar uma variável no meio (total = 100) para ver o que aconteceria.
Os comandos principais
| Comando | Vem de | O que faz |
|---|---|---|
l | list | Mostra o código perto da linha atual (de novo: continua a listagem) |
ll | longlist | Mostra a função inteira em que você está |
n | next | Executa a linha atual e para na próxima, sem entrar nas funções chamadas |
s | step | Executa a linha atual e, se ela chama uma função sua, entra nela |
c | continue | Segue até a próxima parada (ou até o fim) |
p expressão | Mostra o valor da expressão | |
pp expressão | pretty print | Mostra arrumado (bom para listas e dicionários grandes) |
w | where | Mostra o caminho de chamadas até aqui (como um traceback) |
b 6 | break | Marca uma parada na linha 6 (b sozinho lista as paradas) |
cl 1 | clear | Apaga a parada de número 1 |
q | quit | Sai do depurador e encerra o programa |
h / h n | help | Lista os comandos / explica um comando |
| (Enter vazio) | Repete o último comando (útil para apertar n várias vezes) |
Esqueceu o que um comando faz? Pergunte ao próprio pdb:
(Pdb) h n
Usage: n(ext)
Continue execution until the next line in the current function
is reached or it returns.
(Pdb) h p
Usage: p expression
Print the value of the expression.
"Uso: n(ext). Continua a execução até chegar à próxima linha da função atual, ou até ela retornar." O n(ext) quer dizer que você pode digitar n ou next.
No Python 3.14, o código que o pdb mostra (no l, no ll, na linha ->) aparece colorido, como no modo interativo 3.14. As sessões desta página estão sem cor para ficarem fáceis de ler.
4. O programa inteiro no depurador: python3 -m pdb
Você não precisa editar o programa para pôr um breakpoint(). Com python3 -m pdb programa.py, o depurador começa parado na primeira linha. Aqui a Ana usa o s para entrar na função, o w para ver o caminho, o b para marcar uma parada mais adiante e o ll para ver a função inteira:
$ python3 -m pdb carrinho.py
> /home/ana/carrinho.py(1)<module>()
-> def total_com_frete(itens, frete):
(Pdb) n
> /home/ana/carrinho.py(11)<module>()
-> carrinho = [(27.90, 2), (8.49, 3), (4.99, 1)]
(Pdb) n
> /home/ana/carrinho.py(12)<module>()
-> print(f"Total: R$ {total_com_frete(carrinho, 15):.2f}")
(Pdb) s
--Call--
> /home/ana/carrinho.py(1)total_com_frete()
-> def total_com_frete(itens, frete):
(Pdb) n
> /home/ana/carrinho.py(2)total_com_frete()
-> total = 0
(Pdb) n
> /home/ana/carrinho.py(3)total_com_frete()
-> for preco, quantidade in itens:
(Pdb) n
> /home/ana/carrinho.py(4)total_com_frete()
-> subtotal = preco * quantidade
(Pdb) w
/usr/lib/python3.14/bdb.py(913)run()
-> exec(cmd, globals, locals)
<string>(1)<module>()
/home/ana/carrinho.py(12)<module>()
-> print(f"Total: R$ {total_com_frete(carrinho, 15):.2f}")
> /home/ana/carrinho.py(4)total_com_frete()
-> subtotal = preco * quantidade
(Pdb) b 6
Breakpoint 1 at /home/ana/carrinho.py:6
(Pdb) c
> /home/ana/carrinho.py(6)total_com_frete()
-> if total > 100:
(Pdb) p total
4.99
(Pdb) ll
1 def total_com_frete(itens, frete):
2 total = 0
3 for preco, quantidade in itens:
4 subtotal = preco * quantidade
5 total = subtotal
6 B-> if total > 100:
7 frete = 0
8 return total + frete
(Pdb) q
- Começo: parado na linha 1, no
<module>(o "corpo" do arquivo, fora de qualquer função). O primeironpulou da linha 1 para a 11: odefsó cria a função, sem rodar o que está dentro dela. sna linha 12: em vez de executar a linha inteira (como onfaria), osentrou na funçãototal_com_frete. O--Call--avisa "entrei numa chamada".w: o caminho até aqui, de cima para baixo. As duas primeiras linhas são do própriopdb(pode ignorar); depois, a linha 12 do programa, que chamou a função; por último, com o>, onde você está agora.b 6ec: uma parada na linha 6 (logo depois do laço) e "siga até lá". O laço rodou inteiro sem parar, e na linha 6 ototalé 4,99: o valor do último item só.ll: a função inteira. OBmarca a parada; o->, onde você está.q: sai. Aberto compython3 -m pdb, opdbnão pede confirmação.
n (next) | s (step) | |
|---|---|---|
| Numa linha que chama uma função sua | Executa a função inteira e para na linha seguinte | Entra na função e para na primeira linha dela |
| Numa linha comum | Os dois fazem o mesmo: executam a linha e param na próxima | |
| Quando usar | Você confia na função e quer passar por cima | Você desconfia da função e quer ver por dentro |
5. Depois que o programa quebrou: o post mortem
A média da turma dá erro:
def media(notas):
return sum(notas) / len(notas)
turma = {"Ana": [8, 9, 7], "Bia": [], "Caio": [6, 5, 8]}
for aluno, notas in turma.items():
print(aluno, media(notas))
$ python3 media.py
Ana 8.0
Traceback (most recent call last):
File "/home/ana/media.py", line 7, in <module>
print(aluno, media(notas))
~~~~~^^^^^^^
File "/home/ana/media.py", line 2, in media
return sum(notas) / len(notas)
~~~~~~~~~~~^~~~~~~~~~~~
ZeroDivisionError: division by zero
"Divisão por zero." O traceback diz onde, mas não com quais valores. Rodando com python3 -m pdb e mandando seguir (c), o pdb para no momento do erro, com todas as variáveis daquele instante. Isso se chama depuração post mortem ("depois da morte"):
$ python3 -m pdb media.py
> /home/ana/media.py(1)<module>()
-> def media(notas):
(Pdb) c
Ana 8.0
Traceback (most recent call last):
File "/usr/lib/python3.14/pdb.py", line 3652, in main
pdb._run(target)
~~~~~~~~^^^^^^^^
File "/usr/lib/python3.14/pdb.py", line 2566, in _run
self.run(target.code)
~~~~~~~~^^^^^^^^^^^^^
File "/usr/lib/python3.14/bdb.py", line 913, in run
exec(cmd, globals, locals)
~~~~^^^^^^^^^^^^^^^^^^^^^^
File "<string>", line 1, in <module>
File "/home/ana/media.py", line 7, in <module>
print(aluno, media(notas))
~~~~~^^^^^^^
File "/home/ana/media.py", line 2, in media
return sum(notas) / len(notas)
~~~~~~~~~~~^~~~~~~~~~~~
ZeroDivisionError: division by zero
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /home/ana/media.py(2)media()
-> return sum(notas) / len(notas)
(Pdb) p aluno, notas
('Bia', [])
(Pdb) q
O traceback ficou mais comprido (as primeiras linhas são do próprio pdb; o que interessa começa em media.py). Depois vem: "Exceção não tratada. Entrando na depuração post mortem. Rodar cont ou step vai recomeçar o programa." E o (Pdb) está parado exatamente na linha que quebrou. Um p mostra o culpado: a Bia ainda não tem notas, a lista está vazia, e len([]) é 0.
Missão: conserte a média da turma para não quebrar com a lista vazia da Bia: quando o aluno não tiver notas, mostre Bia: sem notas; para os outros, a média com uma casa decimal, como já está.
def media(notas):
return sum(notas) / len(notas)
turma = {"Ana": [8, 9, 7], "Bia": [], "Caio": [6, 5, 8]}
for aluno, notas in turma.items():
print(f"{aluno}: {media(notas):.1f}")
def media(notas):
return sum(notas) / len(notas)
turma = {"Ana": [8, 9, 7], "Bia": [], "Caio": [6, 5, 8]}
for aluno, notas in turma.items():
if notas:
print(f"{aluno}: {media(notas):.1f}")
else:
print(f"{aluno}: sem notas")
Formas diferentes de depurar
| Forma | Como | Quando usar |
|---|---|---|
print(...) | Bilhetes no código; roda de novo | Ver a história inteira (todas as voltas de um laço); defeitos simples |
print(f"{x=}") | O mesmo, com o nome junto | Sempre que for usar print para depurar |
breakpoint() | Pausa naquela linha e abre o pdb | Você sabe onde olhar e quer perguntar várias coisas sem rodar de novo |
python3 -m pdb programa.py | Começa parado na primeira linha | Seguir o programa desde o começo, sem editar o arquivo |
python3 -m pdb + c | Para no momento do erro (post mortem) | O programa quebra e você quer os valores daquele instante |
logging | Mensagens com nível (DEBUG, INFO…), ligadas ou desligadas | Programas que ficam rodando; você quer as pistas guardadas |
| Depurador de um editor (VS Code, PyCharm) | O mesmo que o pdb, com botões e painéis | Quando você já usa um desses editores |
pdb
As sessões desta aula são de um terminal de verdade, onde você digita cada comando e vê a resposta. É lá que vale treinar o pdb: crie o carrinho_bp.py no seu computador e refaça a sessão da seção 3. O breakpoint() também funciona nas caixas "Experimente": o programa para no (Pdb) e você digita p total, n, c… no terminal da caixa (lá, sem as cores). As missões desta página usam a outra lupa, o print.
Quando dá errado
$ python3 carrinho_bp.py > /home/ana/carrinho_bp.py(4)total_com_frete() -> breakpoint() (Pdb) p subtotl *** NameError: name 'subtotl' is not defined (Pdb) subtotal *** NameError: name 'subtotal' is not defined (Pdb) total 0
As linhas com *** são o jeito do pdb mostrar um erro sem derrubar a sessão: você continua no (Pdb). A primeira é um erro de digitação (subtotl). A segunda é mais curiosa: subtotal está escrito certo, mas o programa está parado na linha 4, e o subtotal só é criado na linha 5, que ainda não rodou. Lembre: a linha da setinha -> é a próxima, não a última. Como consertar: confira o nome, ou avance com n até a variável ser criada.
notas = [8, 6, 9]
soma = 0
for n in notas:
breakpoint()
soma += n
print(soma)
$ python3 soma_notas.py > /home/ana/soma_notas.py(4)<module>() -> breakpoint() (Pdb) n > /home/ana/soma_notas.py(5)<module>() -> soma += n (Pdb) p n 8 (Pdb) q Quitting pdb will kill the process. Quit anyway? [y/n] y
A Ana queria ver a variável n, mas n sozinho é o comando next: o programa andou uma linha. Quando o nome da variável é igual a um comando (n, s, c, l, p, q, b, w…), use p na frente: p n. Mais um motivo para dar nomes claros às variáveis: for nota in notas:.
breakpoint() esquecido no código
A Ana mandou o programa para uma colega sem tirar o breakpoint(). Para quem roda, o programa simplesmente "trava" num (Pdb) que ela não pediu. E se o programa roda sem ninguém no teclado (com a entrada vindo de um arquivo, por exemplo), o pdb lê o fim da entrada como "sair":
$ python3 carrinho_bp.py < /dev/null > /home/ana/carrinho_bp.py(4)total_com_frete() -> breakpoint() (Pdb) Quitting pdb will kill the process. Quit anyway? [y/n] $ echo $? 1
O programa terminou no meio, sem mostrar o total, com o código de saída 1 (falha). Como consertar: apague os breakpoint() antes de entregar o programa (procure por eles: grep -n breakpoint *.py). E, para rodar sem as paradas sem editar nada, existe a variável de ambiente PYTHONBREAKPOINT=0, que desliga todos os breakpoint():
$ PYTHONBREAKPOINT=0 python3 carrinho_bp.py Total: R$ 19.99
Não é uma mensagem de erro, mas é o engano mais comum de quem depura. Com o carrinho dando 19,99, dá vontade de "ajustar" o resultado (somar a diferença no fim, mudar o frete) até sair o número certo para aquele carrinho. O próximo carrinho vai dar errado de novo. Depurar é achar a linha em que o valor deixa de ser o esperado (a linha 6, total = subtotal) e consertar ali.
Referência rápida
| Escrita | O que faz |
|---|---|
print(f"{variavel=}") | Mostra variavel=valor |
breakpoint() | Para o programa ali e abre o pdb |
python3 -m pdb programa.py | Roda o programa no depurador, parado na primeira linha; para também se der erro |
PYTHONBREAKPOINT=0 python3 programa.py | Roda ignorando os breakpoint() |
import pdb; pdb.set_trace() | O jeito antigo de escrever breakpoint() (você vai ver em códigos mais velhos) |
l / ll | Código perto da linha atual / a função inteira |
n / s | Próxima linha, passando por cima / entrando nas funções |
c | Continua até a próxima parada |
p x / pp x | Mostra o valor / mostra arrumado |
w | Onde estou (caminho de chamadas) |
b 12 / cl 1 | Parada na linha 12 / apaga a parada 1 |
q | Sai (no 3.14, depois de um breakpoint(), pede confirmação: y) |
h / h comando | Ajuda |
pdb
No Python 3.14, além das cores e da confirmação no q, o pdb ganhou a opção -p PID, que conecta o depurador a um programa Python que já está rodando (python3 -m pdb -p 1234, onde 1234 é o número do processo) 3.14. No Python 3.15, o (Pdb) passou a usar o mesmo editor de linha do modo interativo novo. Veja as Novidades do Python 3.14 e 3.15.
Exercícios
1. O atalho da f-string
Complete o print para que ele mostre preco=27.9:
2. A função que pausa
Qual função embutida, escrita numa linha do programa, faz ele parar ali e abrir o depurador?
3. O pdb está parado numa linha que chama calcular_frete(total), e você quer ver o que acontece dentro dessa função. Qual comando?
4. O pdb mostra -> desconto = preco * 0.1. Nesse momento, a variável desconto…
5. No (Pdb), como ver o valor de uma variável chamada c?
6. Um programa quebra com ZeroDivisionError e você quer ver o valor das variáveis no momento do erro. O que fazer?
Missão final: as vogais da Ana
Missão: a função devia contar as vogais de "Ana Beatriz" (A, a, e, a, i: são 5), mas diz 4. Ponha um print de depuração dentro do for (por exemplo, print(f"{letra=} {total=}")), descubra qual letra não está sendo contada e conserte a função. Depois, apague o print de depuração.
def contar_vogais(texto):
total = 0
for letra in texto:
if letra in "aeiou":
total += 1
return total
print("Vogais:", contar_vogais("Ana Beatriz"))
def contar_vogais(texto):
total = 0
for letra in texto:
if letra.lower() in "aeiou":
total += 1
return total
print("Vogais:", contar_vogais("Ana Beatriz"))
O print mostra a letra 'A' passando sem o total mudar: "A" maiúsculo não está em "aeiou". Há dois consertos: letra.lower() in "aeiou" ou letra in "aeiouAEIOU". E se o texto fosse "Érica"? Pense no que o print mostraria.
Resumo
- Depurar é comparar, ponto a ponto, o que o programa faz com o que você espera, até achar a linha em que os dois se separam.
printmostra a história inteira;print(f"{x=}")põe o nome junto. Apague osprints de depuração no fim.breakpoint()pausa o programa e abre opdb. A linha da setinha->é a próxima a rodar.- Comandos:
llista,npróxima linha,sentra na função,pmostra um valor,ccontinua,qsai (no 3.14, confirme comy); ew,b,ll,h. python3 -m pdb programa.pyroda tudo no depurador; se o programa quebrar, ele para no erro (post mortem).- Variável com nome de comando? Use
p. Não esqueçabreakpoint()no código;PYTHONBREAKPOINT=0desliga todos.