with statement in python

The with statement is used to wrap the execution of a block with methods defined by a context manager. This allows common try...except...finally usage patterns to be encapsulated for convenient reuse.

try:
f = open('/path/to/file', 'r')
print(f.read())
finally:
if f:
f.close()
# use 'with' statement
with open('/path/to/file', 'r') as f:
print(f.read())

How does with statement works?

When execuating a with statment, an object called Context managers are normally invoked.
The context manager handles the entry into, and the exit from, the desired runtime context for the execution of the block of code.

  1. The context expression (the expression given in the with_item) is evaluated to obtain a context manager.

  2. The context manager’s __exit__() is loaded for later use.

  3. The context manager’s __enter__() method is invoked.

  4. If a target was included in the with statement, the return value from __enter__() is assigned to it.

  5. The context manager’s __exit__() method is invoked. If an exception caused the suite to be exited, its type, value, and traceback are passed as arguments to __exit__(). Otherwise, three None arguments are supplied.

class :
def __enter__(self):
set things up
return thing
def __exit__(self, type, value, traceback):
tear things down
with controlled_execution() as thing:
some code

The with statement guarantees that if the __enter__() method returns without an error, then __exit__() will always be called.