PYTHON · 디자인패턴
컨텍스트 매니저 — with & __enter__/__exit__
with 문은 리소스의 획득과 해제를 자동으로 관리합니다. __enter__와 __exit__ 매직 메서드를 구현하거나, contextlib.contextmanager 데코레이터로 간단히 만들 수 있습니다.
디자인패턴중급context-managerwithresource-managementcontextlib
핵심 설명
with 문은 리소스의 획득과 해제를 자동으로 관리합니다. __enter__와 __exit__ 매직 메서드를 구현하거나, contextlib.contextmanager 데코레이터로 간단히 만들 수 있습니다.
Python code
from contextlib import contextmanager
import time
# 1. 클래스 기반 컨텍스트 매니저
class Timer:
def __enter__(self):
self.start = time.perf_counter()
return self # with ... as 변수에 바인딩
def __exit__(self, exc_type, exc_val, exc_tb):
self.elapsed = time.perf_counter() - self.start
print(f"경과 시간: {self.elapsed:.4f}초")
return False # True면 예외를 억제
# 2. 제너레이터 기반 컨텍스트 매니저
@contextmanager
def managed_resource(name):
print(f"[{name}] 리소스 획득")
try:
yield name # with ... as 변수에 전달
except Exception as e:
print(f"[{name}] 예외 발생: {e}")
raise
finally:
print(f"[{name}] 리소스 해제")
# 3. 다중 컨텍스트 매니저
with Timer() as t:
total = sum(range(1_000_000))
print(f"합계: {total}")
with managed_resource("DB") as db:
print(f" {db} 연결로 작업 수행 중...")
# Python 3.10+ 괄호로 여러 개 관리
# with (
# managed_resource("DB") as db,
# managed_resource("Cache") as cache,
# ):
# print(f" {db}와 {cache} 동시 사용")학습 팁
__exit__에서 True를 반환하면 발생한 예외가 억제됩니다. 예외 로깅 후 정상 흐름을 유지하고 싶을 때 유용하지만 남용하면 디버깅이 어려워집니다.
주의할 점
__exit__에서 예외 처리를 깜빡하면 리소스 누수가 발생할 수 있습니다. finally 블록처럼 정리 코드는 반드시 실행되도록 작성하세요.
자주 묻는 질문
컨텍스트 매니저 — with & __enter__/__exit__란 무엇인가요?
with 문은 리소스의 획득과 해제를 자동으로 관리합니다. __enter__ 와 __exit__ 매직 메서드를 구현하거나, contextlib.contextmanager 데코레이터로 간단히 만들 수 있습니다.
컨텍스트 매니저 — with & __enter__/__exit__ 학습 시 주의할 점은 무엇인가요?
__exit__ 에서 예외 처리를 깜빡하면 리소스 누수가 발생할 수 있습니다. finally 블록처럼 정리 코드는 반드시 실행되도록 작성하세요.
Continue Learning
Python 학습을 이어가세요
총 200개의 독립 HTML 학습 문서 중 하나입니다. 각 문서는 고유 URL과 canonical 메타데이터를 가집니다.