Python Context Manager
File Context Manager
Solving: not closing opened files.
A file context manager class contains:
1. An __init__()
method that sets up the object.
2. __enter__()
opens and returns the file.
3. __exit__()
just closes the file
class File(): def __init__(self, filename, mode): self.filename = filename self.mode = mode def __enter__(self): self.file = open(self.filename, self.mode) return self.file def __exit__(self, *args): self.file.close() files = [] for i in range(10000): with File("abc.txt", "r") as f: files.append(f)
Crucially, the variable “f” only exists within the indented block below the with
statement.
Contextlib
The @contextmanager
decorator is a decorator to create context managers. To use it, decorate a generator function that calls yield
exactly once. Everything before the call to yield
is considered the code for __enter__()
. Everything after is the code for __exit__()
.
from contextlib import contextmanager @contextmanager def open_file(path, mode): the_file = open(path, mode) yield the_file the_file.close() files = [] for x in range(100000): with open_file('foo.txt', 'w') as infile: files.append(infile) for f in files: if not f.closed: print('not closed')
ContextDecorator
Define a context manager using the class-based approach, but inheriting from contextlib.ContextDecorator.
from contextlib import ContextDecorator class makeparagraph(ContextDecorator): def __enter__(self): print('<p>') return self def __exit__(self, *exc): print('</p>') return False @makeparagraph() def emit_html(): print('Here is some non-HTML') emit_html()
Reference: https://jeffknupp.com/blog/2016/03/07/python-with-context-managers/