In Python, if I return inside a "with" block, will the file still close?
Yes, it acts like the
finally block after a
try block, i.e. it always executes (unless the python process terminates in an unusual way of course).
It is also mentioned in one of the examples of PEP-343 which is the specification for the
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).
Something worth mentioning is however, that you cannot easily catch exceptions thrown by the
open() call without putting the whole
with block inside a
try..except block which is usually not what one wants.
def example(path, mode): with open(path, mode) as f: return [line for line in f if condition]
..is pretty much equivalent to:
def example(path, mode): f = open(path, mode) try: return [line for line in f if condition] finally: f.close()
More accurately, the
__exit__ method in a context manager is always called when exiting the block (regardless of exceptions, returns etc). The file object's
__exit__ method just calls
f.close() (e.g here in CPython)
Yes. More generally, the
__exit__ method of a With Statement Context Manager will indeed be called in the event of a
return from inside the context. This can be tested with the following:
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()
The output is:
Entering context.Returning inside with-statement.EXITING context.
The output above confirms that
__exit__ was called despite the early
return. As such, the context manager is not bypassed.