2011-08-05 15 views
10

Tengo un código similar al siguiente:Localizar el número de línea donde se produce una excepción en el código Python

try: 
    if x: 
     statement1 
     statement2 
     statement3 
    elif y: 
     statement4 
     statement5 
     statement6 
    else: 
     raise 

except: 
     statement7 

Aquí, estoy seguro de que la excepción se da en If x: bloque, pero me gustaría saber en qué declaración de If x: bloquear la excepción se produce. ¿Hay alguna manera de obtener el número de línea donde ocurre la excepción?

Saludos,

+2

Usted no menciona qué quiere esto. Para depurar un problema? ¿Entonces esa declaración7 puede hacer algo diferente dependiendo de dónde se presentó la excepción? ¿Puedes decirnos más? –

+0

En mi código, la excepción no debería ocurrir en la declaración 1 o en la declaración 2. si lo hace, entonces cualquiera de las declaraciones1 o 2 es incorrecta. es aceptable tenerlo en la declaración3. Es por eso que me gustaría saber en qué línea hay una excepción. – alwbtc

+0

¿Pero qué vas a hacer con la información? ¿Lo necesita una vez para arreglar el programa, o lo necesita en tiempo de ejecución? –

Respuesta

21

qué pasa con esto:

try: 
    if x: 
     print 'before statement 1' 
     statement1 
     print 'before statement 2' #ecc. ecc. 
     statement2 
     statement3 
    elif y: 
     statement4 
     statement5 
     statement6 
    else: 
     raise 

except: 
     statement7 

esta es la solución sencilla pero Es mejor utilizar un depurador

o mejor aún, utilizar el módulo sys: D

try: 
     if x: 
      print 'before statement 1' 
      statement1 
      print 'before statement 2' #ecc. ecc. 
      statement2 
      statement3 
     elif y: 
      statement4 
      statement5 
      statement6 
     else: 
      raise 
except: 
    print sys.exc_traceback.tb_lineno 
    #this is the line number, but there are also other infos 
+0

Actualización: exc_traceback ha sido reemplazado por last_traceback (ej. Https://docs.python.org/2/library/traceback.html) – Daniele

0

editar el código fuente, de manera que se quita una línea a la vez, hasta que desaparece el error, y que tiene que introducir más cerca del problema.

2

Debe envolver las declaraciones que le interesan más estrictamente. Extraer el número de línea de la trazabilidad será complicado y frágil.

+0

La pregunta es interesante como es. Incluso si, por ejemplo, un depurador podría ser mejor que imprimir un rastreo. Con todo, para mí, estás decidiendo simplemente no responder. Cuando llego a esa pregunta, estoy buscando una respuesta al título sobre todo, luego quizás sugerencias sobre cómo codificar/depurar correctamente. – lajarre

2

Si reestructurar el código como tal, usted debe obtener un número de línea cuando la excepción se eleva de nuevo:

except: 
    statement7 
    raise 
+0

¿Debo escribir "raise" después de statement7? ¿Por qué? – alwbtc

+0

SI lo hace como un cambio de depuración temporal, debería ver un seguimiento detallado de la pila con los números de línea cuando ocurra su excepción. –

12

Creo que las diversas respuestas aquí recomendando que administre sus bloques try/except con más fuerza son la respuesta que está buscando. Eso es algo de estilo, no de biblioteca.

Sin embargo, a veces nos encontramos en una situación en la que no es una cuestión de estilo, y realmente do necesita el número de línea para realizar alguna otra acción programática. Si eso es lo que estás preguntando, debes considerar el módulo traceback. Puede extraer toda la información que necesita sobre la excepción más reciente. La función tb_lineno devolverá el número de línea que causa la excepción.

>>> import traceback 
>>> dir(traceback) 
['__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '_format_final_exc_line', '_print', '_some_str', 'extract_stack', 'extract_tb', 'format_exc', 'format_exception', 'format_exception_only', 'format_list', 'format_stack', 'format_tb', 'linecache', 'print_exc', 'print_exception', 'print_last', 'print_list', 'print_stack', 'print_tb', 'sys', 'tb_lineno', 'types'] 
>>> help(traceback.tb_lineno) 
Help on function tb_lineno in module traceback: 

tb_lineno(tb) 
Calculate correct line number of traceback given in tb. 
Obsolete in 2.3 

Las versiones más recientes de la tubería de rastreo solucionar el problema antes de 2.3, lo que permite el código de abajo para trabajar como estaba previsto: (esta es la manera "correcta")

import traceback 
import sys 

try: 
    raise Exception("foo") 
except: 
    for frame in traceback.extract_tb(sys.exc_info()[2]): 
     fname,lineno,fn,text = frame 
     print "Error in %s on line %d" % (fname, lineno) 
+0

gracias, intenté como me dijiste, pero obtuve lo siguiente: se produjo una excepción en el número de línea: < función tb_lineno en 0x2aaaace83140> – alwbtc

+0

tb_lineno es una función, no un atributo. Toma el traceback como un parámetro. Edité la publicación para ser más claro. prueba "print traceback.tb_lineno (sys.exc_info() [2])" - asegúrate de agregar la paren. –

1

El uso de un general Excepto la declaración es generalmente una mala práctica de programación, por lo que debe especificar en su declaración de excepción qué excepción desea capturar. (como excepto ValueError:)

Además, debe rodear con un intento, excepto estructurar los bits de código que se supone que provocan una excepción.

4

Debe ejecutar su programa en un depurador, como pdb. Esto le permitirá ejecutar su código normalmente, y luego examinar el entorno cuando ocurra algo inesperado como este.

Dado un script llamado 'main.py', ejecutarlo así:

python -m pdb main.py 

Entonces, cuando el programa se inicia, se iniciará en el depurador.Escriba c para continuar hasta el próximo punto de interrupción (o bloqueo). Luego, puede examinar el entorno haciendo cosas como print spam.eggs. También puede establecer puntos de interrupción haciendo pdb.set_trace() (normalmente hago import pdb; pdb.set_trace()).

Además, ¿qué quiere decir con que está "bien" que la "declaración 3" presente la excepción? ¿Estás esperando la excepción? Si es así, podría ser mejor escribir un bloque try/except alrededor de esta declaración, para que el programa pueda continuar.

+0

Epic! Trabajó muy bien con Django, ex. 'python -m pdb manage.py syncdb --settings = settings_development' o' python -m pdb manage.py runserver --settings = settings_development'. –

3

que he hecho lo siguiente antes:

try: 
    doing = "statement1" 
    statement1 
    doing = "statement2" 
    statement2 
    doing = "statement3" 
    statement3 
    doing = "statement4" 
    statement4 

except: 
    print "exception occurred doing ", doing 

La ventaja sobre los puestos de control de impresión es que no hay salida del registro a menos existe en realidad es una excepción.

3

Sobre la base de JJ anterior ..

La ventaja de utilizar los errores del sistema a través de afirmaciones es que registran información más específica que ayudará a la depuración posterior (créanme Tengo un montón)

por ejemplo. Los grabo en un archivo de texto, así que después de que mis programas se ejecuten automáticamente durante la noche en el servidor, puedo recuperar cualquier problema y tener suficiente información para acelerar la reparación.

Más información ... Traceback & Sys

import traceback 
import sys 

try: 
    print 1/0 

except Exception as e: 
    print '1', e.__doc__ 
    print '2', sys.exc_info() 
    print '3', sys.exc_info()[0] 
    print '4', sys.exc_info()[1] 
    print '5', sys.exc_info()[2], 'Sorry I mean line...',traceback.tb_lineno(sys.exc_info()[2]) 
    ex_type, ex, tb = sys.exc_info() 
    print '6', traceback.print_tb(tb) 

Rendimientos

> 1 Second argument to a division or modulo operation was zero. 
> 2 (<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division 
>  or modulo by zero',), <traceback object at 0x022DCF30>) 
> 3 <type 'exceptions.ZeroDivisionError'> 
> 4 integer division or modulo by zero 
> 5 <traceback object at 0x022DCF30> Sorry I mean line... 5 
> 6 File "Z:\Programming\Python 2.7\Error.py", line 5, in <module> 
>  print 1/0 
     None 
>>> 
Cuestiones relacionadas