대부분의 튜토리얼은 평범한 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} 초")

왜 이것이 중요한가

  • 코드 블록 자동 타이밍
  • 예외 상황에서도 시간 보고
  • 성능 모니터링 용이

주요 포인트

  1. 컨텍스트 관리자는 파일뿐만이 아닙니다 - 설정/정리가 필요한 모든 리소스에 적용
  2. 예외 안전 - __exit__ 메소드는 예외 상황에서도 항상 호출됨
  3. 조합 가능 - 여러 컨텍스트 관리자 중첩 가능
  4. 재사용 가능 - 한 번 생성, 여러 번 사용

실제 적용

이러한 패턴은 실제 코드에서 매우 유용하며, 특히 데이터베이스 연결, 임시 파일, 네트워크 연결 또는 정확한 타이밍이 필요한 작업을 처리할 때 그렇습니다.

기억하세요: 컨텍스트 관리자는 Python에서 리소스 관리를 위한 스위스 아미 나이프입니다. 이를 사용하는 법을 배우면 코드가 더 견고하고 유지 관리하기 쉬워집니다.