In Python, if I return inside a "with" block, will the file still close? In Python, if I return inside a "with" block, will the file still close? python python

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 statement:

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.


Yes.

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.