The Python standard library contextlib.ExitStack class allows you to manage multiple context managers [^ cm] at once. The advantages of the ExitStack class are listed below.
--Since the ExitStack class is also a context manager, you can specify the scope with with statement.
--Register the context manager included in the instance variable of the class with the __init__ method. Can be managed collectively.
--You can control the call of the __enter__ method by properly using the push method and the ʻenter_context` method.
push method and ʻenter_context` methodThe push method does not call the managed __enter__ method, and the ʻenter_context method calls the managedenter method. Normally, using the ʻenter_context method is fine.
from contextlib import ExitStack
class TestClass:
def __init__(self):
print("TestClass.__init__()")
def __enter__(self):
print("TestClass.__enter__()")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("TestClass.__exit__()")
with ExitStack() as stack:
stack.push(TestClass())
# TestClass.__init__()
# TestClass.__exit__()
with ExitStack() as stack:
stack.enter_context(TestClass())
# TestClass.__init__()
# TestClass.__enter__()
# TestClass.__exit__()
built-in function and manage them with ʻExitStack.It is not overused due to the problem of handle resource management, but you can open and manage the files in the directory at once by combining the ʻExitStack and with` statements.
import os
from contextlib import ExitStack
from typing import List, BinaryIO
#Create / start an ExitStack object with the with statement.
with ExitStack() as stack:
#Get the path of the file in the current directory.
#Exclude directories as the open built-in function fails.
paths: List[str] = [path for path in os.listdir(".") if os.path.isfile(path)]
#Open while adding the file to ExitStack.
files: List[BinaryIO] = [stack.enter_context(open(path, "rb")) for path in paths]
#Process the opened file appropriately.
file: BinaryIO
for file in files:
print(",".join([hex(byte).ljust(2, "0") for byte in file.read(5)]))
#The context manager registered in the ExitStack object (stack)
#Released at the end of the with statement.
--You can use the release process for asynchronous context manager in contextlib.AsyncExitStack class.
[^ cm]: Context manager: An object that implements the __enter__ and __exit__ methods. Reference: Official documentation.
Recommended Posts