대부분의 튜토리얼은 평범한 with open(...) 예제를 보여주고 멈춥니다. 여기 실제 코드에서 실제로 사용하는 세 가지 패턴과 각 패턴이 방지하는 실패 모드가 있습니다.
경우 1: 리소스 정리 및 오류 처리
무엇이든 발생하더라도 정리해야 하는 리소스가 있을 때:
class DatabaseConnection:
def __init__(self, config):
self.config = config
self.connection = None
def __enter__(self):
self.connection = create_connection(self.config)
return self.connection
def __exit__(self, exc_type, exc_val, exc_tb):
if self.connection:
self.connection.close()
왜 이것이 중요한가
- 예외 상황에서도 리소스 정리
- 리소스 누수 방지
- 코드 더 신뢰할 수 있게 만들기
경우 2: 임시 상태 관리
일부 상태를 임시로 변경한 다음 복원해야 할 때:
class TempDir:
def __init__(self, base_path="/tmp"):
self.base_path = base_path
self.temp_path = None
def __enter__(self):
import tempfile
self.temp_path = tempfile.mkdtemp(dir=self.base_path)
return self.temp_path
def __exit__(self, exc_type, exc_val, exc_tb):
import shutil
if self.temp_path and os.path.exists(self.temp_path):
shutil.rmtree(self.temp_path)
왜 이것이 중요한가
- 임시 파일 자동 정리
- 디스크 공간 낭비 방지
- 오류 처리 간소화
경우 3: 성능 모니터링 및 타이밍
코드 실행 시간을 측정해야 할 때:
import time
class Timer:
def __enter__(self):
self.start = time.time()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.end = time.time()
print(f"실행 시간: {self.end - self.start:.2f} 초")
왜 이것이 중요한가
- 코드 블록 자동 타이밍
- 예외 상황에서도 시간 보고
- 성능 모니터링 용이
주요 포인트
- 컨텍스트 관리자는 파일뿐만이 아닙니다 - 설정/정리가 필요한 모든 리소스에 적용
- 예외 안전 -
__exit__메소드는 예외 상황에서도 항상 호출됨 - 조합 가능 - 여러 컨텍스트 관리자 중첩 가능
- 재사용 가능 - 한 번 생성, 여러 번 사용
실제 적용
이러한 패턴은 실제 코드에서 매우 유용하며, 특히 데이터베이스 연결, 임시 파일, 네트워크 연결 또는 정확한 타이밍이 필요한 작업을 처리할 때 그렇습니다.
기억하세요: 컨텍스트 관리자는 Python에서 리소스 관리를 위한 스위스 아미 나이프입니다. 이를 사용하는 법을 배우면 코드가 더 견고하고 유지 관리하기 쉬워집니다.