Variable defined with with-statement available outside of with-block?
PythonPython Problem Overview
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.
Python Solutions
Solution 1 - Python
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.
Solution 2 - Python
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.
Solution 3 - Python
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.
Solution 4 - Python
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).