Python es bastante fresco, pero, por desgracia, el depurador no es tan bueno como perl -d.

Una cosa que puedo hacer es muy frecuente que cuando se experimenta con código para llamar a una función desde el depurador, y el paso en esa función, así:

# NOTE THAT THIS PROGRAM EXITS IMMEDIATELY WITHOUT CALLING FOO()
~> cat -n /tmp/show_perl.pl
1  #!/usr/local/bin/perl
2
3  sub foo {
4      print "hi\n";
5      print "bye\n";
6  }
7
8  exit 0;

~> perl -d /tmp/show_perl.pl

Loading DB routines from perl5db.pl version 1.28
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

main::(/tmp/show_perl.pl:8):    exit 0;

# MAGIC HAPPENS HERE -- I AM STEPPING INTO A FUNCTION THAT I AM CALLING INTERACTIVELY
  DB<1> s foo() 
main::((eval 6)[/usr/local/lib/perl5/5.8.6/perl5db.pl:628]:3):
3:      foo();


  DB<<2>> s
main::foo(/tmp/show_perl.pl:4):     print "hi\n";


  DB<<2>> n
hi
main::foo(/tmp/show_perl.pl:5):     print "bye\n";


  DB<<2>> n
bye


  DB<2> n
Debugged program terminated.  Use q to quit or R to restart,
  use O inhibit_exit to avoid stopping after program termination,
  h q, h R or h O to get additional info.  

  DB<2> q

Esto es increíblemente útil cuando se intenta el paso a través de una función de manejo de las diferentes entradas de averiguar por qué no funciona. Sin embargo, no parece funcionar en cualquiera de los ap o pydb (me gustaría mostrar un equivalente de python ejemplo a la de arriba, pero resulta en una gran pila de la excepción de volcado).

Así que mi pregunta es doble:

  1. Que me estoy perdiendo algo?
  2. Hay un depurador de python que sería, de hecho, permítanme hacer esto?

Obviamente, yo podría poner las llamadas en el código de mí mismo, pero me encanta trabajar de forma interactiva, por ejemplo. no tener que empezar de cero cuando quiero intentar llamar con un conjunto ligeramente diferente de argumentos.

InformationsquelleAutor | 2008-10-23

5 Comentarios

  1. 40

    Y me he respondido a mi pregunta! Es la «depuración» de comandos en pydb:

    ~> cat -n /tmp/test_python.py
         1  #!/usr/local/bin/python
         2
         3  def foo():
         4      print "hi"
         5      print "bye"
         6
         7  exit(0)
         8
    
    ~> pydb /tmp/test_python.py
    (/tmp/test_python.py:7):  <module>
    7 exit(0)
    
    
    (Pydb) debug foo()
    ENTERING RECURSIVE DEBUGGER
    ------------------------Call level 11
    (/tmp/test_python.py:3):  foo
    3 def foo():
    
    ((Pydb)) s
    (/tmp/test_python.py:4):  foo
    4     print "hi"
    
    ((Pydb)) s
    hi
    (/tmp/test_python.py:5):  foo
    5     print "bye"
    
    
    ((Pydb)) s
    bye
    ------------------------Return from level 11 (<type 'NoneType'>)
    ----------------------Return from level 10 (<type 'NoneType'>)
    LEAVING RECURSIVE DEBUGGER
    (/tmp/test_python.py:7):  <module>
  2. 20

    Interactiva puede depurar una función con pdb, siempre que la secuencia de comandos que desea depurar no exit() al final:

    $ cat test.py
    #!/usr/bin/python
    
    def foo(f, g):
            h = f+g
            print h
            return 2*f

    Para depurar, inicio interactivo de python sesión de importación y pdb:

    $ python
    Python 2.5.1 (r251:54869, Apr 18 2007, 22:08:04) 
    [GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import pdb
    >>> import test
    >>> pdb.runcall(test.foo, 1, 2)
    > /Users/simon/Desktop/test.py(4)foo()
    -> h = f+g
    (Pdb) n
    > /Users/simon/Desktop/test.py(5)foo()
    -> print h
    (Pdb) 

    El ap módulo viene con python y está documentado en los módulos docs en http://docs.python.org/modindex.html

  3. 4

    Hay un depurador de python que es parte de la central de distribución de python llamado ‘ap’. Yo casi no la uso yo, pero encuentran que es útil a veces.

    Dado este programa:

    def foo():
        a = 0
        print "hi"
    
        a += 1
    
        print "bye"
    
    foo()

    Aquí es una sesión de depuración es:

    $ python /usr/lib/python2.5/pdb.py /var/tmp/pdbtest.py         ~
    > /var/tmp/pdbtest.py(2)<module>()
    -> def foo():
    (Pdb) s
    > /var/tmp/pdbtest.py(10)<module>()
    -> foo()
    (Pdb) s
    --Call--
    > /var/tmp/pdbtest.py(2)foo()
    -> def foo():
    (Pdb) s
    > /var/tmp/pdbtest.py(3)foo()
    -> a = 0
    (Pdb) s
    > /var/tmp/pdbtest.py(4)foo()
    -> print "hi"
    (Pdb) print a
    0
    (Pdb) s
    hi
    > /var/tmp/pdbtest.py(6)foo()
    -> a += 1
    (Pdb) s
    > /var/tmp/pdbtest.py(8)foo()
    -> print "bye"
    (Pdb) print a
    1
    (Pdb) s
    bye
    --Return--
    > /var/tmp/pdbtest.py(8)foo()->None
    -> print "bye"
    (Pdb) s
    --Return--
    > /var/tmp/pdbtest.py(10)<module>()->None
    -> foo()
    (Pdb) s
  4. 3

    Si usted está más familiarizado con una interfaz gráfica de usuario depurador, hay winpdb (‘ganar’ en este caso no se refiere a Windows). En realidad yo lo uso en Linux.

    En debian/ubuntu:

    sudo aptitude install winpdb

    A continuación, sólo hay que poner esto en el código donde quieres que se rompa:

    import rpdb2; rpdb2.start_embedded_debugger_interactive_password()

    A continuación, iniciar winpdb y adjuntar a su secuencia de comandos en ejecución.

  5. 2

    Para el trabajo interactivo en el código que estoy desarrollando, me suelo encontrar que es más eficaz para establecer el programa «punto de quiebre» en el mismo código con pdb.set_trace. Esto hace que sea easir a romper en el estado del programa en lo más profundo de un bucle, demasiado: if <state>: pdb.set_trace()

Dejar respuesta

Please enter your comment!
Please enter your name here