Post
Python 컨텍스트 매니저(Context Manager) 마스터하기
실무에서 왜 중요한가?
컨텍스트 매니저는 파일 처리, 데이터베이스 연결, 락(Lock) 관리 등에서 리소스를 안전하게 획득하고 해제하는 패턴입니다.
with 문을 사용하면 예외 발생 여부와 관계없이 정리 코드가 항상 실행되므로, 메모리 누수와 연결 고갈을 방지할 수 있습니다.
핵심 개념
-
__enter__()메서드with블록 진입 시 호출되며, 리소스를 획득하고 반환합니다. -
__exit__()메서드with블록 종료 시 항상 호출되며, 리소스를 정리합니다. 예외 정보도 받습니다. -
contextlib.contextmanager데코레이터 클래스 대신 제너레이터 함수로 간단하게 컨텍스트 매니저를 만들 수 있습니다. -
예외 처리
__exit__()메서드에서True를 반환하면 예외를 억제할 수 있습니다. -
다중 컨텍스트 매니저 여러 리소스를 한 번에 관리할 수 있습니다.
실습 예제
클래스 기반 컨텍스트 매니저
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
print(f"파일 열기: {self.filename}")
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"파일 닫기: {self.filename}")
if self.file:
self.file.close()
return False
# 사용 예
with FileManager('test.txt', 'w') as f:
f.write('Hello, Context Manager!')
데코레이터 기반 컨텍스트 매니저
from contextlib import contextmanager
@contextmanager
def database_connection(db_name):
print(f"DB 연결: {db_name}")
connection = f"Connection to {db_name}"
try:
yield connection
finally:
print(f"DB 종료: {db_name}")
# 사용 예
with database_connection('mydb') as conn:
print(f"쿼리 실행: {conn}")
다중 컨텍스트 매니저
with open('input.txt', 'r') as infile, open('output.txt', 'w') as outfile:
for line in infile:
outfile.write(line.upper())
예외 처리 예제
class ErrorHandler:
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_type is ValueError:
print(f"ValueError 처리됨: {exc_val}")
return True # 예외 억제
return False
# 사용 예
with ErrorHandler():
raise ValueError("이 에러는 억제됩니다")
print("프로그램 계속 실행")
자주 하는 실수
-
__exit__()메서드 반환값 무시__exit__()에서True를 반환해야만 예외가 억제됩니다. 반환값이 없으면 예외가 전파됩니다. -
리소스 정리 코드를
__exit__()에 넣지 않기 정리 코드를__enter__()나 블록 내부에 넣으면, 예외 발생 시 실행되지 않을 수 있습니다. -
제너레이터 함수에서
finally블록 빼먹기@contextmanager사용 시finally블록이 없으면 리소스가 정리되지 않습니다. -
다중 컨텍스트에서 순서 무시 여러 리소스를 관리할 때 획득 순서와 반대로 해제되어야 합니다.
with문은 이를 자동으로 처리합니다. -
__exit__()메서드에서 새로운 예외 발생 정리 중 예외가 발생하면 원래 예외가 가려질 수 있습니다. 신중하게 처리하세요.
오늘의 실습 체크리스트
- 클래스 기반 컨텍스트 매니저 구현하고 테스트하기
@contextmanager데코레이터로 간단한 매니저 만들기- 파일 I/O에서
with문 사용하기 - 다중 컨텍스트 매니저 작성하고 실행하기
__exit__()메서드의 예외 처리 로직 구현하기- 예외 발생 시 리소스가 제대로 정리되는지 확인하기
댓글