Using The 'with' statement in python

The "with" Statement PEP was created way back in 2005, PEP 343 to be precise, but /me notice many still coding with old syntax with is not bad, but does not look clean?!

So thought of making a small entry here, about using the with statement in python.

PEP 304 was originally written in first person by Guido, and subsequently updated by Nick Coghlan to reflect later discussion on python-dev. Any first person references are from Guido's original.

Traditional error handling would be to try something, except exception and finally do something else.

  <setup>
        try:
            <variable> = <value>
            <body>
        except Exception:
            <process exception>
        finally:
            <cleanup>

But above can be reduced with the 'with' statement as below :

with_stmt ::=  "with" with_item ("," with_item)* ":" suite
with_item ::=  expression ["as" target]

Consider the below example, for some clarity :

# Opening a file in the required mode
 
"""
for file in openFile('/var/log/h3manth.log',"r"):
    data = file.read()
    print data
"""
 
def openFile(filename,mode):
    f = open(filename, mode)
    try:
        yield f
    finally:
        f.close()

The above code, can be re-written using the 'with' statement as below :

with open('/var/log/h3manth.log', "r") as fh:
     data = fh.read()

Some more fun with context managers Python 2.7+ :

import contextlib
 
@contextlib.contextmanager
def enter_stage(name):
    print name,' is entering the stage!'
    yield name
    print name,' is at the side-wing.'
 
with enter_stage('Antony') as A, enter_stage('Hop') as H, enter_stage('Kins') as K:
    print 'inside with statement:', A, H, K

Would result in an output as below :

Antony is entering the stage!
Hop is entering the stage!
Kin is entering the stage!
inside with statement: A H K
Antony is at the side-wing.
Hop is at the side-wing.
Kin is at the side-wing.

It's important to note that :

with A() as a, B() as b:
    suite
 
#is equivalent to :
 
with A() as a:
    with B() as b:
        suite

If you have still not bad a habit of using 'with' please do!

Share this