Python Contextlib ExitStack
Python’s contextlib
provides a ContextManager, ExitStack
that makes managing other context managers driven by data.
ExitStack instance provides a method enter_context
which registers a context manager and handles enter and exit special methods.
This method is useful when there are more than one context manager or nested context managers or to create context manager on the fly.
Example
from contextlib import ContextDecorator, ExitStack
from typing import Union
from pathlib import Path
class BackupFile(ContextDecorator):
def __init__(self, name: Union[Path, str]):
self.path = Path(name)
def __enter__(self):
print(f'-Creating backup file for {self.path}-')
def __exit__(self, type, value, traceback):
print(f'--Deleting the backup file for {self.path}--')
def get_filenames():
# data from command line
return ['destroy.txt', 'cant_create.txt']
def main():
# This will not print any statement
print('Calling the class outside of context manager')
BackupFile("destroy.txt")
print('Calling the class with ExitStack and should print statements')
# This should print enter and exit print statement
with ExitStack() as stack:
filenames = get_filenames()
files = [stack.enter_context(BackupFile(fname)) for fname in filenames]
# edit file
print('* Unit of Work *')
# invoke some function and you can pass the stack
if __name__ == "__main__":
main()
$python backup_file.py
Calling the class outside of context manager
Calling the class with ExitStack and should print statements
-Creating backup file for destroy.txt-
-Creating backup file for cant_create.txt-
* Unit of Work *
--Deleting the backup file for cant_create.txt--
--Deleting the backup file for destroy.txt--
Link to a sample usage from CPython source code.