Recientemente conocí un ejemplo de código que nunca había visto antes:

try:
    # a simple bunch of code
    if sample == 0:
        return True
    else:
        raise ExampleError()
except not ExampleError:
    raise AnotherExampleError()

¿Cómo funciona (si es que funciona)?

7
kevlar 10 may. 2019 a las 15:49

3 respuestas

La mejor respuesta

EDITAR: La respuesta a continuación fue para Python 3, no me di cuenta de la pregunta relacionada con Python 2.7. en Python 2, como parece, el intérprete no se queja si la expresión después de except no da como resultado un subtipo de BaseException. Sin embargo, el comportamiento sigue siendo incorrecto, simplemente ignorará ese bloque except en todos los casos.


Esa es una construcción divertida que es sintácticamente válida pero semánticamente incorrecta. Supongo que el autor del código tenía la intención de expresar algo como "ejecutar este bloque except para cualquier tipo de excepción que no sea ExampleError". Sin embargo, lo que realmente está sucediendo es más como:

try:
    # ...
except (not bool(ExampleError)):
    # ...

Cuando se genera una excepción en el bloque try, Python pasa por los diferentes bloques except buscando uno que coincida con el tipo de excepción. Cuando ve except not ExampleError, equivalente a except (not bool(ExampleError)), da como resultado except False, que no es válido porque False no es un subtipo de BaseException (o una tupla de subtipos de BaseException). Por lo tanto, el código puede incluso ejecutarse si no se generan excepciones, pero es incorrecto.

8
jdehesa 10 may. 2019 a las 13:16

Hasta donde yo sé, esto no tendrá éxito en ninguna versión de Python. Debido a que el operador no siempre da como resultado un valor booleano (True o False) esto está tratando de atrapar uno de esos valores aquí, en este caso False. Como no puedes lanzar True o False, no hay uso para esto.

Creo que la intención del autor fue algo como esto:

try:
    raise ExampleError()
except ExampleError e:
    throw e
except:
    raise AnotherExampleError()
3
Quinn Mortimer 10 may. 2019 a las 13:09

Una prueba rápida muestra que el código arrojará un TypeError si alcanza esa línea:

try:
  raise BaseException
except not BaseException:
  print("Test1")
except BaseException:
  print("Test2")

Excepción:

Durante el control de la excepción anterior, se produjo otra excepción:

Rastreo (última llamada más reciente): archivo "main.py", línea 3, excepto BaseException: TypeError: no se permite la captura de clases que no heredan de BaseException

1
AK47 10 may. 2019 a las 12:55