Para cualquier bloque try-finally posible en Python, ¿está garantizado que el finally bloque siempre se ejecutará?
Por ejemplo, digamos que vuelvo mientras estoy en un bloque except :
try: 1/0 except ZeroDivisionError: return finally: print("Does this code run?") O tal vez vuelva a plantear una Exception :
try: 1/0 except ZeroDivisionError: raise finally: print("What about this code?") Las pruebas muestran que finally se ejecuta para los ejemplos anteriores, pero imagino que hay otros escenarios en los que no he pensado.
¿Hay algún escenario en el que un bloque finally no pueda ejecutarse en Python?
Si. Finalmente siempre gana.
La única forma de vencerlo es detener la ejecución antes de que finally: tenga la oportunidad de ejecutar (por ejemplo, bloquee el intérprete, apague su computadora, suspenda un generador para siempre).
Me imagino que hay otros escenarios en los que no he pensado.
Aquí hay un par más en los que quizás no hayas pensado:
def foo(): # finally always wins try: return 1 finally: return 2 def bar(): # even if he has to eat an unhandled exception, finally wins try: raise Exception('boom') finally: return 'no boom'Dependiendo de cómo salga del intérprete, a veces puede "cancelar" finalmente, pero no así:
>>> import sys >>> try: ... sys.exit() ... finally: ... print('finally wins!') ... finally wins! $ Usando el precario os._exit (en mi opinión, esto se incluye en "bloquear el intérprete"):
>>> import os >>> try: ... os._exit(1) ... finally: ... print('finally!') ... $Actualmente estoy ejecutando este código, para probar si finalmente se ejecutará después de la muerte por calor del universo:
try: while True: sleep(1) finally: print('done')Sin embargo, todavía estoy esperando el resultado, así que vuelva a consultar aquí más tarde.
De acuerdo con la documentación de Python :
No importa lo que haya sucedido anteriormente, el bloque final se ejecuta una vez que se completa el bloque de código y se manejan las excepciones generadas. Incluso si hay un error en un controlador de excepciones o en el bloque else y se genera una nueva excepción, el código en el bloque final aún se ejecuta.
También se debe tener en cuenta que si hay varias instrucciones de devolución, incluida una en el bloque finalmente, la devolución del bloque finalmente es la única que se ejecutará.