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/