4

Is this code

with open(myfile) as f:
    data = f.read()
    process(data)

equivalent to this one

try:
    f = open(myfile)
    data = f.read()
    process(f)
finally:
    f.close()

or the following one?

f = open(myfile)
try:
    data = f.read()
    process(f)
finally:
    f.close()

This article: http://effbot.org/zone/python-with-statement.htm suggests (if I understand it correctly) that the latter is true. However, the former would make more sense to me. If I am wrong, what am I missing?

3
  • 1
    It's not equivalent to either. What if process raises an error? with does not handle errors here, but the other two do. Commented Dec 20, 2015 at 14:57
  • 1
    @ajcr: neither does try:...finally:. The second stanza is equivalent. Commented Dec 20, 2015 at 14:59
  • My mistake. I somehow read except when it wasn't there. Commented Dec 20, 2015 at 15:00

2 Answers 2

5

According to the documentation:

A new statement is proposed with the syntax:

with EXPR as VAR:
    BLOCK

The translation of the above statement is:

mgr = (EXPR)
exit = type(mgr).__exit__  # Not calling it yet
value = type(mgr).__enter__(mgr)
exc = True
try:
    try:
        VAR = value  # Only if "as VAR" is present
        BLOCK
    except:
        # The exceptional case is handled here
        exc = False
        if not exit(mgr, *sys.exc_info()):
            raise
        # The exception is swallowed if exit() returns true
finally:
    # The normal and non-local-goto cases are handled here
    if exc:
        exit(mgr, None, None, None)

And this is an extended version of your second code snippet. Initialization goes before try ... finaly block.

Sign up to request clarification or add additional context in comments.

Comments

3

It's equivalent to the latter one, because until open() successfully returns, f has no value, and should not be closed.

3 Comments

with will always close the file for you. How does the second example do that?
@agconti If open() fails, the file was never opened, so it doesn’t need to be closed either.
@agconti If open() raises an exception, f is never even initialized. Not only that there is no reason to close f, but f.close() would raise NameError: name 'f' is not defined if you tried.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.