컨텍스트 매니저는 코드 블록을 진입하고 나올 때 자동으로 설정 및 정리 작업을 수행하는 데 사용된다. 일반적으로 with
문과 함께 사용되며, 자원 관리(파일, 네트워크 연결, 락 등)에 유용하다. 파이썬에서는 두 가지 방법으로 컨텍스트 매니저를 구현할 수 있다: __enter__
및 __exit__
메서드를 사용하거나, contextlib
모듈의 데코레이터를 사용하는 방법이 있다.
기본 사용법
컨텍스트 매니저는 with
문을 사용하여 구현된다. 다음은 파일을 열고 자동으로 닫는 예제이다.
with open('example.txt', 'w') as file:
file.write('Hello, World!')
위 예제에서 with
문이 끝나면 파일이 자동으로 닫힌다.
__enter__ 및 __exit__ 메서드를 사용한 구현
컨텍스트 매니저를 직접 구현하려면, 클래스에 __enter__
와 __exit__
메서드를 정의해야 한다.
class MyContextManager:
def __enter__(self):
print("Entering the context")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Exiting the context")
# 사용 예시
with MyContextManager():
print("Inside the context")
위 예제에서 with
블록에 진입하면 __enter__
메서드가 호출되고, 블록을 빠져나오면 __exit__
메서드가 호출된다.
__enter__
__enter__
메서드는 with
블록에 진입할 때 호출된다. 이 메서드는 선택적으로 값을 반환할 수 있으며, with
문 내에서 사용할 수 있다.
class Resource:
def __enter__(self):
print("Acquiring resource")
return self
def do_something(self):
print("Using resource")
def __exit__(self, exc_type, exc_val, exc_tb):
print("Releasing resource")
# 사용 예시
with Resource() as resource:
resource.do_something()
__exit__
__exit__
메서드는 with
블록을 벗어날 때 호출된다. 이 메서드는 네 개의 인자를 받으며, 각각 예외의 타입, 값, 트레이스백을 나타낸다. 예외가 발생하지 않으면 None
이 전달된다.
class Resource:
def __enter__(self):
print("Acquiring resource")
return self
def do_something(self):
print("Using resource")
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type:
print(f"Exception: {exc_val}")
print("Releasing resource")
# 사용 예시
with Resource() as resource:
resource.do_something()
# 일부러 예외 발생
raise ValueError("Something went wrong")
응용 예제
다음은 데이터베이스 연결을 관리하는 컨텍스트 매니저의 예제이다.
class DatabaseConnection:
def __enter__(self):
print("Connecting to the database")
self.connection = self.connect()
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
self.connection.close()
print("Closing the database connection")
def connect(self):
# 가상의 데이터베이스 연결
class Connection:
def close(self):
print("Connection closed")
return Connection()
# 사용 예시
with DatabaseConnection() as conn:
print("Using the database connection")
contextlib 모듈을 사용한 구현
contextlib
모듈을 사용하면 더 간편하게 컨텍스트 매니저를 구현할 수 있다. contextlib.contextmanager
데코레이터를 사용하면 함수 기반의 컨텍스트 매니저를 만들 수 있다.
from contextlib import contextmanager
@contextmanager
def my_context_manager():
print("Entering the context")
yield
print("Exiting the context")
# 사용 예시
with my_context_manager():
print("Inside the context")