with statement open manager español decorators context python return with-statement

statement - En Python, si regreso dentro de un bloque "con", ¿el archivo aún se cerrará?



with python español (3)

Sí, actúa como el bloque finally después de un bloque try , es decir, siempre se ejecuta (a menos que el proceso de python finalice de una manera inusual, por supuesto).

También se menciona en uno de los ejemplos de PEP-343 que es la especificación para la declaración with :

with locked(myLock): # Code here executes with myLock held. The lock is # guaranteed to be released when the block is left (even # if via return or by an uncaught exception).

Algo que vale la pena mencionar es, sin embargo, que no se pueden capturar fácilmente las excepciones lanzadas por la llamada a open() sin poner todo el bloque dentro de un try..except bloque que generalmente no es lo que uno quiere.

Considera lo siguiente:

with open(path, mode) as f: return [line for line in f if condition]

¿El archivo se cerrará correctamente, o el uso de return alguna manera omite el administrador de contexto ?


Sí. De manera más general, el método __exit__ de un Gestor de Contexto de Statement se llamará en caso de que se produzca un return desde dentro del contexto. Esto se puede probar con lo siguiente:

class MyResource: def __enter__(self): print(''Entering context.'') return self def __exit__(self, *exc): print(''EXITING context.'') def fun(): with MyResource(): print(''Returning inside with-statement.'') return print(''Returning outside with-statement.'') fun()

El resultado es:

Entering context. Returning inside with-statement. EXITING context.

El resultado anterior confirma que se llamó __exit__ pesar del return anticipado. Como tal, el administrador de contexto no se pasa por alto.


Sí.

def example(path, mode): with open(path, mode) as f: return [line for line in f if condition]

..es más o menos equivalente a:

def example(path, mode): f = open(path, mode) try: return [line for line in f if condition] finally: f.close()

Más exactamente, el método __exit__ en un administrador de contexto siempre se llama al salir del bloque (independientemente de las excepciones, devoluciones, etc.). El método __exit__ del objeto de __exit__ solo llama a f.close() (por ejemplo, aquí en CPython )