A context manager that is designed to make it easy to programmatically combine other context managers and cleanup functions, especially those that are optional or otherwise driven by input data.
class contextlib.ExitStack
with ExitStack() as stack:
files = [stack.enter_context(open(fname)) for fname in filenames]
All opened files will automatically be closed at the end of
the with statement, even if attempts to open files later
in the list raise an exception
with ExitStack() as stack:
files = [stack.enter_context(open(fname)) for fname in filenames]
Hold onto the close method, but don't call it yet.
close_files = stack.pop_all().close
If opening any file fails, all previously opened files will be
closed automatically. If all files are opened successfully,
they will remain open even after the with statement ends.
close_files() can then be invoked explicitly to close them all.