Use a Python with statement to work with a file, and show that the file is closed afterwards.
The with statement runs a block and guarantees the resource is released when the block ends, whether it ended normally or with an exception.
import os
import tempfile
path = os.path.join(tempfile.gettempdir(), "tutorsbot_with.txt")
with open(path, "w", encoding="utf-8") as handle:
handle.write("hello with\n")
print(handle.closed) # True - closed when the block ended
with open(path, encoding="utf-8") as handle:
print(handle.read().strip())
os.remove(path)The first line is the point of the whole construct. After the with block, the file object's closed attribute is True, and that is true even if an exception had been raised inside the block — the file would still be closed, and the exception would still propagate.
Behind the syntax, the file object is a context manager. It implements __enter__, which returns the resource to bind to the target name, and __exit__, which is called when the block finishes. The with statement is really just a tidier way of writing a try/finally pair.
You can write your own context managers, and the class-based form is worth recognising.
class Managed:
def __enter__(self):
print("enter")
return self
def __exit__(self, exc_type, exc, tb):
print("exit")
return False # do not suppress exceptions
with Managed():
print("body")
The output is enter, body, exit. The value returned by __exit__ decides whether an exception is swallowed — returning False, or None, lets it propagate, while returning True suppresses it.