without try print poner exceptions example error como catch and all python exception-handling

print - Python try-else



try except python example (20)

Python try-else

¿Cuál es el uso previsto de la cláusula else opcional de la instrucción try?

Resumen

La instrucción else ejecuta si no hay excepciones y si no es interrumpida por una return , continue o break .

Las otras respuestas pierden esa última parte.

De la documentación:

La cláusula else opcional se ejecuta cuando el control fluye fuera del final de la cláusula try . *

(Bolding añadido.) Y la nota al pie lee:

* Actualmente, el control "fluye fuera del final", excepto en el caso de una excepción o la ejecución de una return de return , continue o break .

Requiere al menos una cláusula de excepción ( vea la gramática ). Entonces realmente no es "try-else", es "try-except-else (-finally)", con el else (y finally ) siendo opcional.

El tutorial de Python elabora sobre el uso previsto:

La sentencia try ... except tiene una cláusula else opcional, que, cuando está presente, debe seguir todas las cláusulas excepto. Es útil para el código que debe ejecutarse si la cláusula try no genera una excepción. Por ejemplo:

for arg in sys.argv[1:]: try: f = open(arg, ''r'') except IOError: print ''cannot open'', arg else: print arg, ''has'', len(f.readlines()), ''lines'' f.close()

El uso de la cláusula else es mejor que agregar código adicional a la cláusula try porque evita la captura accidental de una excepción que no fue generada por el código protegido por la declaración try ... except.

Ejemplo de diferenciación de lo else frente al código que sigue al bloque try

Si maneja un error, el bloque else no se ejecutará. Por ejemplo:

def handle_error(): try: raise RuntimeError(''oops!'') except RuntimeError as error: print(''handled a RuntimeError, no big deal.'') else: print(''if this prints, we had no error!'') # won''t print! print(''And now we have left the try block!'') # will print!

Y ahora,

>>> handle_error() handled a RuntimeError, no big deal. And now we have left the try block!

¿Cuál es el uso previsto de la cláusula else opcional de la instrucción try ?


A menudo puede existir un bloque else para complementar la funcionalidad que se produce en cada bloque except .

try: test_consistency(valuable_data) except Except1: inconsistency_type = 1 except Except2: inconsistency_type = 2 except: # Something else is wrong raise else: inconsistency_type = 0 """ Process each individual inconsistency down here instead of inside the except blocks. Use 0 to mean no inconsistency. """

En este caso, inconsistency_type se establece en cada bloque excepto, por lo que el comportamiento se complementa en el caso de no error en else .

Por supuesto, estoy describiendo esto como un patrón que puede aparecer en su propio código algún día. En este caso específico, simplemente establece inconsistency_type en 0 antes del bloque try todos modos.


A pesar de que no puedes pensar en un uso en este momento, puedes apostar que tiene que haber un uso para él. Aquí hay una muestra poco imaginativa:

Con else

a = [1,2,3] try: something = a[2] except: print "out of bounds" else: print something

Sin else

try: something = a[2] except: print "out of bounds" if "something" in locals(): print something

Aquí tienes la variable something definido si no se produce ningún error. Puede eliminar esto fuera del bloque try , pero luego requiere un poco de detección desordenada si se define una variable.


Aquí hay otro lugar donde me gusta usar este patrón:

while data in items: try data = json.loads(data) except ValueError as e: log error else: # work on the `data`


De errores y excepciones # Manejar excepciones - docs.python.org

La sentencia try ... except tiene una cláusula else opcional, que, cuando está presente, debe seguir todas las cláusulas excepto. Es útil para el código que debe ejecutarse si la cláusula try no genera una excepción. Por ejemplo:

for arg in sys.argv[1:]: try: f = open(arg, ''r'') except IOError: print ''cannot open'', arg else: print arg, ''has'', len(f.readlines()), ''lines'' f.close()

El uso de la cláusula else es mejor que agregar código adicional a la cláusula try porque evita la captura accidental de una excepción que no fue generada por el código protegido por la declaración try ... except.


El else: bloque es confuso y (casi) inútil. También es parte de las declaraciones for y while .

En realidad, incluso en una declaración if , la else: puede ser abusada de una manera verdaderamente terrible creando errores que son muy difíciles de encontrar.

Considera esto.

if a < 10: # condition stated explicitly elif a > 10 and b < 10: # condition confusing but at least explicit else: # Exactly what is true here? # Can be hard to reason out what condition is true

Piensa dos veces en else: Generalmente es un problema. Evítelo, excepto en una declaración if e incluso luego considere documentar la condición else para hacerlo explícito.


En cuanto a la referencia de Python , parece que else se ejecuta después de un try cuando no hay excepción. La cláusula else opcional se ejecuta cuando el control fluye fuera del final de la cláusula try. 2 excepciones en la cláusula else no son manejadas por las cláusulas de excepción anteriores.

2 tiene un ejemplo en el que, si entiendo correctamente, en el bloque try intentan importar un módulo, cuando eso falla, se obtiene una excepción y un enlace por defecto, pero cuando funciona, tiene la opción de entrar en el bloque else y enlazar lo que se requiere. (ver enlace para el ejemplo y explicación).

Si intentas hacer un trabajo en el bloque catch , podría lanzar otra excepción: supongo que ahí es donde el bloque else es útil.


Eso es. El bloque ''else'' de una cláusula try-except existe para el código que se ejecuta cuando (y solo cuando) la operación intentada tiene éxito. Puede ser utilizado, y puede ser abusado.

try: fp= open("configuration_file", "rb") except EnvironmentError: confdata= '''' # it''s ok if the file can''t be opened else: confdata= fp.read() fp.close() # your code continues here # working with (possibly empty) confdata

Personalmente, me gusta y lo uso cuando sea apropiado. Agrupa semánticamente enunciados.


Hay un buen ejemplo de try-else en PEP 380 . Básicamente, se trata de hacer un manejo de excepciones diferente en diferentes partes del algoritmo.

Es algo como esto:

try: do_init_stuff() except: handle_init_suff_execption() else: try: do_middle_stuff() except: handle_middle_stuff_exception()

Esto le permite escribir el código de manejo de excepciones más cerca de donde ocurre la excepción.


Hay una gran razón para usar else : estilo y legibilidad. En general, es una buena idea mantener un código que pueda causar excepciones cerca del código que trata con ellos. Por ejemplo, compara estos:

try: from EasyDialogs import AskPassword # 20 other lines getpass = AskPassword except ImportError: getpass = default_getpass

y

try: from EasyDialogs import AskPassword except ImportError: getpass = default_getpass else: # 20 other lines getpass = AskPassword

La segunda es buena cuando la except no puede regresar antes o volver a lanzar la excepción. De ser posible, habría escrito:

try: from EasyDialogs import AskPassword except ImportError: getpass = default_getpass return False # or throw Exception(''something more descriptive'') # 20 other lines getpass = AskPassword

Nota: La respuesta se copió de un duplicado recientemente publicado here , por lo tanto, todo esto "AskPassword".


He encontrado else útil para tratar con un archivo de configuración posiblemente incorrecto:

try: value, unit = cfg[''lock''].split() except ValueError: msg = ''lock monitoring config must consist of two words separated by white space'' self.log(''warn'', msg) else: # get on with lock monitoring if config is ok

Una excepción que lee la configuración de lock desactiva la supervisión de bloqueo y ValueErrors registra un mensaje de advertencia útil.


He encontrado el try: ... else: construye útil en la situación en la que estás ejecutando consultas de base de datos y registrando los resultados de esas consultas en una base de datos separada del mismo tipo / tipo. Digamos que tengo muchos subprocesos de trabajo, todas las consultas de bases de datos de manejo enviadas a una cola

#in a long running loop try: query = queue.get() conn = connect_to_db(<main db>) curs = conn.cursor() try: curs.execute("<some query on user input that may fail even if sanitized">) except DBError: logconn = connect_to_db(<logging db>) logcurs = logconn.cursor() logcurs.execute("<update in DB log with record of failed query") logcurs.close() logconn.close() else: #we can''t put this in main try block because an error connecting #to the logging DB would be indistinguishable from an error in #the mainquery #We can''t put this after the whole try: except: finally: block #because then we don''t know if the query was successful or not logconn = connect_to_db(<logging db>) logcurs = logconn.cursor() logcurs.execute("<update in DB log with record of successful query") logcurs.close() logconn.close() #do something in response to successful query except DBError: #This DBError is because of a problem with the logging database, but #we can''t let that crash the whole thread over what might be a #temporary network glitch finally: curs.close() conn.close() #other cleanup if necessary like telling the queue the task is finished

Por supuesto, si puede distinguir entre las posibles excepciones que podrían lanzarse, no tiene que usar esto, pero si el código que reacciona a una pieza de código exitosa puede lanzar la misma excepción que la pieza exitosa, y no puede simplemente Deje pasar la segunda excepción posible, o regrese inmediatamente después de tener éxito (lo que mataría el hilo en mi caso), entonces esto es útil.


La mayoría de las respuestas parecen concentrarse en por qué no podemos simplemente poner el material en la cláusula else en la cláusula try. La pregunta else en la declaración de prueba ... ¿para qué sirve específicamente el por qué el código de la cláusula else no puede ir después del bloque try en sí mismo, y esa pregunta se confunde a esta, pero no veo una respuesta clara a esa pregunta? aquí. Siento que https://.com/a/3996378/1503120 responde de manera excelente a esa pregunta. También he tratado de dilucidar los diversos significados de las distintas cláusulas en https://.com/a/22579805/1503120 .


Las instrucciones en el bloque else se ejecutan si la ejecución cae fuera de la parte inferior del try , si no hubo excepción. Sinceramente, nunca he encontrado una necesidad.

Sin embargo, manejo de notas de excepciones :

El uso de la cláusula else es mejor que agregar código adicional a la cláusula try porque evita la captura accidental de una excepción que no fue generada por el código protegido por la declaración try ... except.

Entonces, si tiene un método que podría, por ejemplo, lanzar un IOError , y quiere atrapar las excepciones que genera, pero hay algo más que quiere hacer si la primera operación tiene éxito, y no quiere atrapar un IOError de esa operación, podrías escribir algo como esto:

try: operation_that_can_throw_ioerror() except IOError: handle_the_exception_somehow() else: # we don''t want to catch the IOError if it''s raised another_operation_that_can_throw_ioerror() finally: something_we_always_need_to_do()

Si acaba de poner another_operation_that_can_throw_ioerror() después de operation_that_can_throw_ioerror , except los errores de la segunda llamada. Y si lo pones después de todo el bloque try , siempre se ejecutará, y no hasta después del finally . El else te permite asegurarte

  1. la segunda operación solo se ejecuta si no hay excepción,
  2. se ejecuta antes del bloque finally , y
  3. cualquier IOError s que plantea no está atrapado aquí

Me parece realmente útil cuando tienes que hacer una limpieza que se debe hacer, incluso si hay una excepción:

try: data = something_that_can_go_wrong() except Exception as e: # yes, I know that''s a bad way to do it... handle_exception(e) else: do_stuff(data) finally: clean_up()


Quizás un uso podría ser:

#debug = [] def debuglog(text, obj=None): " Simple little logger. " try: debug # does global exist? except NameError: pass # if not, don''t even bother displaying except: print(''Unknown cause. Debug debuglog().'') else: # debug does exist. # Now test if you want to log this debug message # from caller "obj" try: if obj in debug: print(text) # stdout except TypeError: print(''The global "debug" flag should be an iterable.'') except: print(''Unknown cause. Debug debuglog().'') def myfunc(): debuglog(''Made it to myfunc()'', myfunc) debug = [myfunc,] myfunc()

Tal vez esto te lleve también a un uso.


Supongamos que su lógica de programación depende de si un diccionario tiene una entrada con una clave determinada. Puede probar el resultado de dict.get(key) utilizando if... else... construct, o puede hacer:

try: val = dic[key] except KeyError: do_some_stuff() else: do_some_stuff_with_val()


Try-except-else es ideal para combinar el patrón EAFP con duck-typing :

try: cs = x.cleanupSet except AttributeError: pass else: for v in cs: v.cleanup()

Podrías pensar que este código ingenuo está bien:

try: for v in x.cleanupSet: v.clenaup() except AttributeError: pass

Esta es una excelente manera de ocultar accidentalmente errores graves en su código. Escribí la limpieza allí, pero el AttributeError que me dejaría saber está siendo tragado. Peor aún, ¿qué pasaría si lo hubiera escrito correctamente, pero el método de limpieza se pasaba de vez en cuando a un tipo de usuario que tenía un atributo mal llamado, lo que provocaba que fallara silenciosamente a la mitad y dejaba un archivo sin cerrar? Buena suerte depurando esa.


Un uso: probar algún código que debería generar una excepción.

try: this_should_raise_TypeError() except TypeError: pass except: assert False, "Raised the wrong exception type" else: assert False, "Didn''t raise any exception"

(Este código debe resumirse en una prueba más genérica en la práctica).


Uno de los escenarios de uso que se me ocurren son las excepciones impredecibles, que se pueden eludir si lo intenta de nuevo. Por ejemplo, cuando las operaciones en el bloque de prueba involucran números aleatorios:

while True: try: r = random.random() some_operation_that_fails_for_specific_r(r) except Exception: continue else: break

Pero si la excepción se puede predecir, siempre debe elegir la validación de antemano sobre una excepción. Sin embargo, no todo puede predecirse, por lo que este patrón de código tiene su lugar.