2010-01-21 24 views
11

tengo algo de código en un pitón except cláusula que se pretende hacer un poco de registro, pero el código de registro podría causar por sí misma una excepción. En mi caso, me gustaría simplemente ignorar cualquier segunda excepción que pueda ocurrir y plantear la excepción original. Aquí está un ejemplo muy simplificado:Manejo de una excepción de Python que se produce dentro de una cláusula de excepción

try: 
    a = this_variable_doesnt_exist 
except: 
    try: 
     1/0 
    except: 
     pass 
    raise 

Ejecutar el código anterior, espero conseguir:

NameError: name 'this_variable_doesnt_exist' is not defined 

pero en cambio, en Python 2.x, me sale:

ZeroDivisionError: integer division or modulo by zero 

Descubrí que en Python 3.x, hace lo que quiero.

no pude encontrar muchos comentarios al respecto en la documentación de Python 2.x (a menos que me lo perdí). ¿Puedo lograr esto en 2.x?

Respuesta

15

con la abstracción:

def log_it(): 
    try: 
     1/0 
    except: 
     pass 

try: 
    this = that 
except: 
    log_it() 
    raise 

hace lo que quiere en Python 2.5

Otra manera de hacerlo es la de almacenar la excepción en una variable, a continuación, volver a subir de forma explícita:

try: 
    this = that 
except NameError, e: # or NameError as e for Python 2.6 
    try: 
     1/0 
    except: 
     pass 
    raise e 

Tenga en cuenta que es probable que no sólo debe estar usando un desnudo except para atrapar todo lo que pueda venir - por lo general es la mejor manera de detectar las excepciones específicas que se pueden esperar t o ocurrir en caso de que ocurra una excepción drástica y fatal (como estar fuera de la memoria).

18

Creo que lo que se está viendo es el resultado de exception chaining, que es un change in Python 3.

Desde el sección motivación de la PEP:

Durante el manejo de una excepción (excepción A), es posible que se puede producir otra excepción (excepción B). En Python de hoy (versión 2.4), si esto sucede, la excepción B se propaga hacia afuera y se pierde la excepción A. Para depurar el problema, es útil conocer ambas excepciones. El atributo __context__ conserva esta información automáticamente.

El PEP luego describe el nuevo encadenamiento de excepciones (que se implementa en Py3k) en detalle — es una lectura interesante. Aprendí algo nuevo hoy.

+0

¿cómo se debe manejar de manera explícita la excepción secundaria? Por favor, incluya esto en su respuesta –

0

En mi CausedException class me encargo de eso para Python 2.x (y para Python 3 también, en caso de que desee pasar árboles de causa en lugar de cadenas de causa simples). Puede que esto te ayude.

+1

Si bien esto puede responder a la pregunta en teoría, [sería preferible] (http://meta.stackexchange.com/q/8259) para incluir las partes esenciales de la respuesta aquí, y proporcionar el enlace para referencia. –

Cuestiones relacionadas