Dicas de depuração do Python [fechadas]


164

Quais são as suas melhores dicas para depurar Python?

Por favor, não liste apenas um depurador em particular sem dizer o que ele realmente pode fazer.

Relacionado


Respostas:


139

APO

Você pode usar o módulo pdb, inserir em pdb.set_trace()qualquer lugar e ele funcionará como um ponto de interrupção.

>>> import pdb
>>> a="a string"
>>> pdb.set_trace()
--Return--
> <stdin>(1)<module>()->None
(Pdb) p a
'a string'
(Pdb)

Para continuar a execução, use c(ou contou continue).

É possível executar expressões arbitrárias em Python usando pdb. Por exemplo, se você encontrar um erro, poderá corrigir o código e digitar uma expressão de tipo para ter o mesmo efeito no código em execução

ipdb é uma versão do pdb para IPython . Ele permite o uso do pdb com todos os recursos do IPython, incluindo o preenchimento de guias.

Também é possível definir o pdb para executar automaticamente em uma exceção não capturada.

O Pydb foi escrito para ser uma versão aprimorada do Pdb. Benefícios?


Aqui está um artigo sobre o uso do pdb: sontek.net/debugging-python-with-pdb
sontek

Pessoalmente, eu gosto mais do ipdb .
Sardathrion - contra abuso de SE

1
Aparentemente há uma reescrita de pydb chamado pydbgr
Ehtesh Choudhury

Sublime text tem uma grande plugin para adicionar pontos de interrupção Python para código: sublime.wbond.net/packages/Python%20Breakpoints
Dennis Golomazov

Se você estiver desenvolvendo um aplicativo Web, adicione uma exibição myserver.com/pdbno modo de depuração que simplesmente faz import pdb; pdb.set_trace(). Se você estiver usando o Flask / Werkzeug que possui um depurador interativo, também é possível ter uma exibição assert False.
osa 28/09

78

http://pypi.python.org/pypi/pudb , um depurador Python em tela cheia e baseado em console.

Seu objetivo é fornecer todos os detalhes dos depuradores modernos baseados em GUI em um pacote mais leve e fácil de usar. O PuDB permite depurar o código exatamente onde você o escreve e testa - em um terminal. Se você trabalhou com as excelentes (mas hoje em dia antigas) ferramentas Turbo Pascal ou C baseadas em DOS, a interface do usuário do PuDB pode parecer familiar.

captura de tela pudb

Bom para depurar scripts independentes, basta executar

python -m pudb.run my-script.py

Instale compip install pudb
congusbongus

40

Se você estiver usando pdb, poderá definir aliases para atalhos. Eu uso estes:

# Ned's .pdbrc

# Print a dictionary, sorted. %1 is the dict, %2 is the prefix for the names.
alias p_ for k in sorted(%1.keys()): print "%s%-15s= %-80.80s" % ("%2",k,repr(%1[k]))

# Print the instance variables of a thing.
alias pi p_ %1.__dict__ %1.

# Print the instance variables of self.
alias ps pi self

# Print the locals.
alias pl p_ locals() local:

# Next and list, and step and list.
alias nl n;;l
alias sl s;;l

# Short cuts for walking up and down the stack
alias uu u;;u
alias uuu u;;u;;u
alias uuuu u;;u;;u;;u
alias uuuuu u;;u;;u;;u;;u
alias dd d;;d
alias ddd d;;d;;d
alias dddd d;;d;;d;;d
alias ddddd d;;d;;d;;d;;d

Como você define esses alias?
Casebash 26/10/09

9
Coloque essas coisas em ~ / .pdbrc
Ned Batchelder

No Windows você pode colocá-lo em ~ / _ipython / ipythonrc.ini
fastmultiplication

33

Exploração madeireira

O Python já possui um excelente módulo de log embutido . Você pode usar o modelo de log aqui .

O módulo de registro permite especificar um nível de importância; durante a depuração, você pode registrar tudo, enquanto durante a operação normal, você pode registrar apenas coisas críticas. Você pode desligar e ligar as coisas.

A maioria das pessoas usa apenas instruções básicas de impressão para depurar e remove as instruções de impressão. É melhor deixá-los dentro, mas desativá-los; então, quando você tiver outro bug, basta reativar tudo e examinar seus logs.

Essa pode ser a melhor maneira possível de depurar programas que precisam fazer as coisas rapidamente, como programas de rede que precisam responder antes que a outra extremidade da conexão expire e desapareça. Você pode não ter muito tempo para executar uma etapa em um depurador; mas você pode simplesmente deixar seu código rodar e registrar tudo, depois examinar os logs e descobrir o que realmente está acontecendo.

EDIT: O URL original dos modelos era: http://aymanh.com/python-debugging-techniques

Como esta página está ausente, substituí-a por uma referência ao instantâneo salvo em archive.org: http://web.archive.org/web/20120819135307/http://aymanh.com/python-debugging-techniques

Caso desapareça novamente, aqui estão os modelos que mencionei. Este é um código retirado do blog; Eu não escrevi.

import logging
import optparse

LOGGING_LEVELS = {'critical': logging.CRITICAL,
                  'error': logging.ERROR,
                  'warning': logging.WARNING,
                  'info': logging.INFO,
                  'debug': logging.DEBUG}

def main():
  parser = optparse.OptionParser()
  parser.add_option('-l', '--logging-level', help='Logging level')
  parser.add_option('-f', '--logging-file', help='Logging file name')
  (options, args) = parser.parse_args()
  logging_level = LOGGING_LEVELS.get(options.logging_level, logging.NOTSET)
  logging.basicConfig(level=logging_level, filename=options.logging_file,
                      format='%(asctime)s %(levelname)s: %(message)s',
                      datefmt='%Y-%m-%d %H:%M:%S')

  # Your program goes here.
  # You can access command-line arguments using the args variable.

if __name__ == '__main__':
  main()

E aqui está sua explicação de como usar o descrito acima. Novamente, não recebo o crédito por isso:


Por padrão, o módulo de registro imprime mensagens críticas, de erro e de aviso. Para alterar isso para que todos os níveis sejam impressos, use:

$ ./your-program.py --logging=debug

Para enviar mensagens de log para um arquivo chamado debug.log, use:

$ ./your-program.py --logging-level=debug --logging-file=debug.log


1
O problema com o módulo de log é que ele quebra muito com o Unicode e várias soluções alternativas são necessárias para que ele funcione em aplicativos internacionalizados. Porém, essa ainda é a melhor solução de log para Python.
Jacek Konieczny

O link "modelo de log aqui" está morto. Por favor atualize.
Yohann

20

É possível imprimir quais linhas Python são executadas (obrigado Geo!). Isso tem vários aplicativos, por exemplo, você pode modificá-lo para verificar quando determinadas funções são chamadas ou adicionar algo como ## para rastrear apenas linhas específicas.

code.interact leva você a um console interativo

import code; code.interact(local=locals())

Se você quiser acessar facilmente o histórico do console, consulte: " Posso ter um mecanismo de histórico como o shell? " (Terá que procurar por ele).

O preenchimento automático pode ser ativado para o intérprete .


19

O ipdb é como o pdb, com a grandiosidade do ipython.


5
Você poderia adicionar mais detalhes sobre o que ele pode fazer?
Casebash

17

print afirmações

  • Algumas pessoas recomendam uma debug_printfunção em vez de imprimir para facilitar a desativação
  • O pprintmódulo é inestimável para estruturas complexas

3
+1 quando todos os depuradores falham, print é seu amigo, sim debug_print seria uma boa adição
Anurag Uniyal

Eu geralmente imprimir primeiro e depois depuração segunda exceto quando eu sei que eu vou ser capaz de resolver traçando uma seção específica
Casebash

4
Na verdade, o módulo de log faz exatamente isso.
e-satis

É verdade, mas o log deve ser configurado. Vou aprender a usar o módulo depois de honras
Casebash

A impressão pode ser útil em casos simples e principalmente no desenvolvimento de projetos com pouco tempo de inicialização. Por outro lado, pode ser viciante e usá-lo através do pdb ou de qualquer outro depurador em cenários mais complexos geralmente causará dores de cabeça.
vinilios

16

a maneira óbvia de depurar um script

python -m pdb script.py
  • útil quando esse script gera uma exceção
  • útil ao usar o comando virtualenv e pdb não está sendo executado com a versão venvs python.

se você não sabe exatamente onde está esse script

python -m pdb ``which <python-script-name>``

15

PyDev

O PyDev tem um bom depurador interativo. Ele possui expressões de observação, lista suspensa para avaliar, listas de encadeamentos e pilhas e (quase) todas as comodidades usuais que você espera de um depurador visual moderno. Você pode até se conectar a um processo em execução e fazer depuração remota.

Porém, como outros depuradores visuais, acho útil principalmente para problemas simples ou para problemas muito complicados depois de tentar tudo o resto. Eu ainda faço a maior parte do trabalho pesado com o registro.


Ele tem a capacidade de editar e continuar?
Casebash

@ CaseBash, não, mas esse recurso está planejado. Mesmo sem ele, porém, a velocidade e facilidade de configuração / breakpoints desactivação e olhando através de valores variáveis ainda é muito útil
Jiaaro


12

O Winpdb é muito bom e, ao contrário do nome, é completamente multiplataforma.

Ele tem um ótimo depurador de GUI e baseado em prompt , e suporta depuração remota.


@Casebash - adicionado mais detalhes
orip 26/10/09

1
+1 Este é o único depurador python que eu encontrei até agora que pode lidar com multi-threading.
Lee Netherton

Tenha cuidado com o seu "manuseio" de multiencadeamento - qualquer exceção em qualquer encadeamento faz com que todo o processo congele. Não é uma coisa ruim se você está ciente disso, muito doloroso se você não é
Walt W

O projeto parece morto a partir de abril de 2014
Alojz Janez 20/04

7

No Vim, eu tenho essas três ligações:

map <F9> Oimport rpdb2; rpdb2.start_embedded_debugger("asdf") #BREAK<esc>
map <F8> Ofrom nose.tools import set_trace; set_trace() #BREAK<esc>
map <F7> Oimport traceback, sys; traceback.print_exception(*sys.exc_info()) #TRACEBACK<esc>

rpdb2é um depurador remoto do Python, que pode ser usado com o WinPDB, um depurador gráfico sólido. Porque eu sei que você perguntará, ele pode fazer tudo o que eu espero que um depurador gráfico faça :)

Uso pdbde nose.toolspara depurar testes de unidade e código normal.

Por fim, o F7mapeamento imprimirá um retorno (semelhante ao que você obtém quando uma exceção borbulha no topo da pilha). Eu achei isso realmente útil mais do que algumas vezes.


4

Definindo métodos repr () úteis para suas classes (para que você possa ver o que é um objeto) e usando repr () ou "% r"% (...) ou "... {0! R} ..". Format (...) em suas mensagens / logs de depuração é IMHO uma chave para uma depuração eficiente.

Além disso, os depuradores mencionados em outras respostas farão uso dos métodos repr ().


2

Obtendo um rastreamento de pilha de um aplicativo Python em execução

Existem vários truques aqui . Esses incluem

  • Invadir um intérprete / imprimir um rastreamento de pilha enviando um sinal
  • Obtendo um rastreamento de pilha de um processo Python não preparado
  • Executando o interpretador com sinalizadores para torná-lo útil para depuração

2

Se você não gosta de gastar tempo com depuradores (e não aprecia a pouca usabilidade da pdbinterface da linha de comandos), pode despejar o rastreio de execução e analisá-lo mais tarde. Por exemplo:

python -m trace -t setup.py install > execution.log

Isso irá despejar toda a linha de setup.py installexecução de origem para execution.log.

Para facilitar a personalização da saída do rastreio e escrever seus próprios rastreadores, reuni algumas partes do código no módulo xtrace (domínio público).


1

Quando possível, depuro usando M-x pdbno emacs para depuração no nível da fonte.


1

Existe um curso on-line completo chamado " Software Debugging ", de Andreas Zeller, sobre o Udacity, com dicas sobre depuração:

Resumo do Curso

Nesta aula, você aprenderá como depurar programas sistematicamente, como automatizar o processo de depuração e criar várias ferramentas de depuração automatizada no Python.

Por que fazer este curso?

No final deste curso, você terá um sólido entendimento sobre depuração sistemática, saberá como automatizar a depuração e criará várias ferramentas funcionais de depuração no Python.

Pré-requisitos e Requisitos

É necessário conhecimento básico de programação e Python no nível do Udacity CS101 ou melhor. O entendimento básico da programação orientada a objetos é útil.

Altamente recomendado.


0

se você quiser uma boa maneira gráfica de imprimir sua pilha de chamadas de forma legível, confira este utilitário: https://github.com/joerick/pyinstrument

Execute a partir da linha de comando:

python -m pyinstrument myscript.py [args...]

Execute como um módulo:

from pyinstrument import Profiler

profiler = Profiler()
profiler.start()

# code you want to profile

profiler.stop()
print(profiler.output_text(unicode=True, color=True))

Execute com django:

Basta adicionar pyinstrument.middleware.ProfilerMiddlewarepara MIDDLEWARE_CLASSES, em seguida, adicionar ?profileao final da URL pedido para ativar o gerador de perfil.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.