Variable defined with with-statement available outside of with-block?

Question:

Consider the following example:

with open('a.txt') as f:
    pass
# Is f supposed to be defined here?

I have read the language docs (2.7) for with-statement as well as PEP-343, but as far as I can tell they don’t say anything on this matter.

In CPython 2.6.5 f does seem to be defined outside of the with-block, but I’d rather not rely on an implementation detail that could change.

Asked By: Heikki Toivonen

||

Answers:

In case f is a file, it will be appear closed outside the with statement.

For example, this

f = 42
print f
with open('6432134.py') as f:
    print f
print f

would print:

42
<open file '6432134.py', mode 'r' at 0x10050fb70>
<closed file '6432134.py', mode 'r' at 0x10050fb70>

You can find the details in PEP-0343 under the section Specification: The ‘with’ Statement. Python scope rules (which might be irritating) apply to f as well.

Answered By: miku

the with syntax:

with foo as bar:
    baz()

is approximately sugar for:

try:
    bar = foo.__enter__()
    baz()
finally:
    if foo.__exit__(*sys.exc_info()) and sys.exc_info():
        raise

This is often useful. For example

import threading
with threading.Lock() as myLock:
    frob()

with myLock:
    frob_some_more()

the context manager may be of use more than once.

To answer Heikki’s question in the comments: yes, this scoping behavior is part of the python language specification and will work on any and all compliant Pythons (which includes PyPy, Jython, and IronPython).

Answered By: Alex Gaynor

Yes, the context manager will be available outside the with statement and that is not implementation or version dependent. with statements do not create a new execution scope.

Answered By: fuzzyman
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.