Toothpick Anemone
Toothpick Anemone

Reputation: 4636

If you were to explicitly call the `__enter__()` and `__exit_()` methods instead of using a `with` statement, what would the code look like?

If you were to explicitly call the __enter__() and __exit_() methods instead of using a with statement, what would the code look like?

Code using a with statement:

with open("test.txt", "w") as file:
    file.write("Hello, World!")

Failed attempt to re-write the code

The goal is to replace the with-statement with explicit calls to __enter__() and __exit__()

file = open("test.txt", "w")
try:
    file.__enter__()
    file.write("Hello, World!")
    file.__exit__()
except BaseException as exc:
    exc_class, exc_object, traceback = something_some_some()
    file.__exit__(exc_class, exc_object, traceback)
finally:
    pass   

Upvotes: 0

Views: 64

Answers (1)

chepner
chepner

Reputation: 532053

Following the desugaring at https://docs.python.org/3/reference/compound_stmts.html#the-with-statement:

manager = open("test.txt", "w")
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
hit_except = False

try:
    file = value
    file.write("Hello, World!")
except:
    hit_except = True
    if not exit(manager, *sys.exc_info()):
        raise
finally:
    if not hit_except:
        exit(manager, None, None, None)

Note that the bare except is intentional here; any exception should trigger the __exit__ method. Saving bound methods for __enter__ and __exit__ is done, I think, to prevent __enter__ from being executed before verifying that the supposed context manager actually has an __exit__ method.

Upvotes: 2

Related Questions