Python inspect: Rastreie Linhas e Depure Scripts em 2026
Leitura: ~9 min
TL;DR
- inspect.currentframe() entrega o número exato da linha sendo executada — mas é um recurso de diagnóstico, não de produção: o overhead de captura de frame é real e mensurável.
- A combinação sys.exc_info() + traceback é mais precisa para rastrear erros do que inspect isolado — ela sobe toda a pilha de chamadas e identifica o arquivo, função e linha original da exceção.
- O insight mais valioso deste post: um decorator @debug_line reutilizável que injeta rastreamento automático de linha em qualquer função sem modificar o código original — padrão que usamos aqui no @CanalQb.
Conclusão: Para projetos grandes em Python, a stack correta é inspect + logging + traceback. Cada um tem seu papel — e usá-los juntos é o que separa debug amador de diagnóstico profissional.
Nota Técnica: Os exemplos apresentados têm fins exclusivamente educacionais e de diagnóstico em ambiente de desenvolvimento. Nunca exponha informações de stack trace ou número de linha ao usuário final em aplicações de produção — isso representa risco de segurança (information disclosure). O @CanalQb não se responsabiliza por usos inadequados. Conteúdo gerado com auxílio de IA — revisado e validado pela equipe @CanalQb (Lei Felca nº 15.211/2025).
Você está com um script de 800 linhas quebrando em algum lugar. O erro aparece, o traceback aponta para uma função intermediária — mas a causa raiz está três camadas abaixo. O print("aqui1") espalhado pelo código já não dá mais conta do recado.
O módulo inspect existe exatamente para esse momento. Ele expõe a pilha de execução do Python em tempo real, sem precisar de debugger externo, sem IDE, sem plugin. Funciona em scripts simples, em automações, em bots rodando em servidor — em qualquer lugar onde o Python roda.
Aqui está o detalhe que quase ninguém menciona: inspect isolado resolve metade do problema. A outra metade vem de como você combina ele com logging e traceback. Nos projetos de automação com Python do @CanalQb, adotamos um padrão específico que vai além do exemplo básico — e você vai ver ele completo aqui.
O que é o módulo inspect do Python e para que ele serve?
O inspect é um módulo da biblioteca padrão do Python que fornece acesso à estrutura interna de objetos em tempo de execução: funções, classes, módulos, frames de execução e a pilha de chamadas completa. Ele faz parte do Python desde a versão 2.1 e não requer instalação.
| Função | O que retorna | Caso de uso |
|---|---|---|
| inspect.currentframe() | Frame da função atual | Saber a linha sendo executada agora |
| inspect.stack() | Lista de todos os frames da pilha | Ver toda a cadeia de chamadas até o ponto atual |
| inspect.getfile(obj) | Caminho do arquivo onde o objeto foi definido | Identificar qual módulo originou a chamada |
| inspect.getsource(obj) | Código-fonte do objeto como string | Inspecionar código de funções em runtime |
| inspect.signature(func) | Assinatura da função (parâmetros e tipos) | Validação dinâmica de parâmetros |
| inspect.getmembers(obj) | Lista de todos os atributos e métodos | Introspecção de classes e módulos |
Como usar inspect.currentframe() para rastrear a linha atual de execução?
O currentframe() retorna o frame do Python que está sendo executado naquele exato momento. Cada frame contém o número da linha (f_lineno), o nome da função (f_code.co_name) e o arquivo (f_code.co_filename).
import inspect
def mostrar_linha_atual():
frame = inspect.currentframe()
lineno = frame.f_lineno
funcao = frame.f_code.co_name
arquivo = frame.f_code.co_filename
print(f"[TRACE] Arquivo : {arquivo}")
print(f"[TRACE] Função : {funcao}()")
print(f"[TRACE] Linha : {lineno}")
print("-" * 40)
# IMPORTANTE: sempre libere o frame para evitar referências circulares
del frame
mostrar_linha_atual()
# Código adicional
mostrar_linha_atual()
[TRACE] Arquivo : /home/usuario/meu_script.py
[TRACE] Função : mostrar_linha_atual()
[TRACE] Linha : 4
----------------------------------------
[TRACE] Arquivo : /home/usuario/meu_script.py
[TRACE] Função : mostrar_linha_atual()
[TRACE] Linha : 4
Como capturar o número da linha onde o erro ocorreu com sys.exc_info()?
Para rastrear erros, a combinação sys.exc_info() com o objeto traceback é mais confiável que inspect isolado — ela percorre toda a pilha de chamadas e localiza a linha original da exceção, não apenas onde ela foi capturada. Este é um padrão essencial para qualquer trabalho de debug avançado com Python.
import inspect
import sys
import traceback
def funcao_profunda():
x = variavel_inexistente # Linha que causa o NameError
def funcao_intermediaria():
funcao_profunda()
def funcao_principal():
funcao_intermediaria()
try:
funcao_principal()
except Exception as e:
# sys.exc_info() retorna (tipo, valor, traceback)
tipo, valor, tb = sys.exc_info()
# tb_lineno: linha onde a exceção OCORREU (não onde foi capturada)
linha_erro = tb.tb_lineno
# Para subir até a origem real na pilha:
while tb.tb_next:
tb = tb.tb_next
linha_origem = tb.tb_lineno
arquivo_origem = tb.tb_frame.f_code.co_filename
funcao_origem = tb.tb_frame.f_code.co_name
print(f"Tipo do erro : {tipo.__name__}")
print(f"Mensagem : {valor}")
print(f"Capturado na linha : {linha_erro}")
print(f"Origem real : {funcao_origem}() — linha {linha_origem}")
print(f"Arquivo : {arquivo_origem}")
print("\n--- Stack completa ---")
traceback.print_exc()
Tipo do erro : NameError
Mensagem : name 'variavel_inexistente' is not defined
Capturado na linha : 15
Origem real : funcao_profunda() — linha 6
Arquivo : /home/usuario/meu_script.py
--- Stack completa ---
Traceback (most recent call last):
File "meu_script.py", line 15, in <module>
funcao_principal()
File "meu_script.py", line 12, in funcao_principal
funcao_intermediaria()
File "meu_script.py", line 9, in funcao_intermediaria
funcao_profunda()
File "meu_script.py", line 6, in funcao_profunda
NameError: name 'variavel_inexistente' is not defined
Como usar inspect.stack() para ver toda a pilha de chamadas sem erro?
O inspect.stack() retorna a pilha de execução completa mesmo sem exceção — ideal para logar o caminho percorrido até um ponto específico do código. Cada item da lista é um FrameInfo com arquivo, linha, função e contexto de código.
import inspect
def mostrar_pilha_completa():
pilha = inspect.stack()
print(f"{'Nível':<6 70="" arquivo="" code="" def="" del="" do="" enumerate="" f="" for="" frame_info="" frames="" funcao:="" funcao="frame_info.function" in="" inha="" libera="" linha:="" linha="frame_info.lineno" mostrar_pilha_completa="" nivel:="" nivel="" nivel_a="" nivel_b="" nivel_c="" nome="" o="" os="" pilha="" print="" rquivo="" s="" todos="" un="">6>
Como criar um decorator @debug_line para rastreamento automático de qualquer função?
Este é o padrão mais poderoso do post — e o que usamos internamente nos scripts do @CanalQb. Um decorator que injeta rastreamento de linha em qualquer função sem alterar uma linha do código original. Basta adicionar @debug_line antes da definição da função.
import inspect
import functools
import logging
# Configura logging para arquivo + console
logging.basicConfig(
level=logging.DEBUG,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[
logging.FileHandler("debug_trace.log", encoding="utf-8"),
logging.StreamHandler()
]
)
log = logging.getLogger("CanalQb")
def debug_line(func):
"""
Decorator que loga automaticamente:
- Arquivo, função e linha de entrada
- Argumentos recebidos
- Linha de saída e valor retornado
- Exceção e linha exata em caso de erro
"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
frame = inspect.currentframe()
caller = inspect.stack()[1]
entrada = caller.lineno
arquivo = caller.filename.split("/")[-1]
log.debug(
f"ENTER → {func.__name__}() | "
f"chamado de {arquivo}:{entrada} | "
f"args={args} kwargs={kwargs}"
)
del frame
try:
resultado = func(*args, **kwargs)
log.debug(f"EXIT ← {func.__name__}() | retornou: {resultado!r}")
return resultado
except Exception as exc:
_, _, tb = __import__("sys").exc_info()
while tb.tb_next:
tb = tb.tb_next
log.error(
f"ERRO em {func.__name__}() | "
f"linha {tb.tb_lineno} | "
f"{type(exc).__name__}: {exc}"
)
raise # Re-lança para não engolir a exceção
return wrapper
# ──── Uso ────────────────────────────────────────
@debug_line
def calcular(a, b):
return a / b # ZeroDivisionError se b == 0
@debug_line
def processar_dados(lista):
return [calcular(x, x - 1) for x in lista]
processar_dados([3, 2, 1]) # O último item causará ZeroDivisionError
2026-06-02 [DEBUG] ENTER → processar_dados() | chamado de script.py:44 | args=([3, 2, 1],)
2026-06-02 [DEBUG] ENTER → calcular() | chamado de script.py:41 | args=(3, 2)
2026-06-02 [DEBUG] EXIT ← calcular() | retornou: 1.5
2026-06-02 [DEBUG] ENTER → calcular() | chamado de script.py:41 | args=(2, 1)
2026-06-02 [DEBUG] EXIT ← calcular() | retornou: 2.0
2026-06-02 [DEBUG] ENTER → calcular() | chamado de script.py:41 | args=(1, 0)
2026-06-02 [ERROR] ERRO em calcular() | linha 32 | ZeroDivisionError: division by zero
Quando usar inspect e quando usar o módulo logging em Python?
São ferramentas complementares, não concorrentes. O inspect extrai informações de contexto de execução; o logging é o canal por onde essas informações trafegam de forma estruturada, persistente e controlável. Confira a estratégia completa de logging profissional em Python nos conteúdos do @CanalQb.
Boas práticas para depuração profissional com inspect em Python
Sempre libere o frame com del frame
Frames do Python mantêm referências para variáveis locais, o que pode criar ciclos de referência e atrasar o garbage collector. Após usar inspect.currentframe(), sempre execute del frame — ou use a variável dentro de um bloco try/finally para garantia.
Use inspect apenas em modo debug — nunca em hot paths
A captura de frames tem custo real de CPU. Em loops de alta frequência (milhares de iterações por segundo), usar inspect.stack() pode degradar a performance em 10x ou mais. Proteja com uma flag de debug: if DEBUG: mostrar_linha_atual().
Integre com o módulo logging em vez de usar print()
O logging permite controlar o nível de detalhe (DEBUG, INFO, WARNING, ERROR) sem alterar o código — basta mudar a configuração. Em produção, eleve o nível para WARNING; em desenvolvimento, mantenha DEBUG. O print() não tem esse controle e polui stdout em produção.
Combine com o módulo traceback para erros em threads
Em scripts com múltiplas threads, sys.exc_info() retorna informações apenas da thread atual. Para capturar exceções de outras threads, use traceback.format_exc() dentro do handler de erro de cada thread e envie o resultado para o logger principal.
Perguntas Frequentes
Qual a diferença entre inspect.currentframe() e inspect.stack() em Python?
O módulo inspect do Python tem impacto na performance em produção?
Como rastrear a linha de erro em Python sem usar o módulo inspect?
Como salvar o rastreamento de linhas em um arquivo de log com Python?
O inspect.currentframe() funciona dentro de funções aninhadas e lambdas em Python?
Como identificar qual módulo ou arquivo externo causou uma exceção em Python?
É possível usar inspect para depurar scripts Python que rodam em servidor sem GUI?
Fontes e Referências
Quer mais Python do jeito certo?
Scripts, automações e técnicas que funcionam de verdade — direto do @CanalQb, toda semana.
Acessar o @CanalQb no YouTubeFeito com Master Rules Claude v8.1 | @CanalQb © 2026
ssssssssssssssssssss

Comentários
Comente só assim vamos crescer juntos!