Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬 컨텍스트 관리자의 이해: __enter__와 __exit__ 메서드 활용법

파이썬에서 with 문은 런타임 컨텍스트(runtime context)를 지원하는 핵심 구문입니다. 이 컨텍스트는 컨텍스트 관리자(context manager)에 의해 정의되며, 컨텍스트 관리자를 활용하면 사용자가 직접 클래스를 만들어 런타임 컨텍스트를 정의할 수 있습니다.

컨텍스트 관리자는 with 문의 본문(body)이 실행되기 전에 진입하여 작업을 시작하고, 본문의 실행이 끝나면 자동으로 종료됩니다. 덕분에 파일 열기/닫기처럼 리소스를 반드시 해제해야 하는 작업을 안전하게 처리할 수 있습니다.

컨텍스트 관리자의 두 가지 핵심 메서드

컨텍스트 관리자 프로토콜을 구현하려면 다음 두 가지 특수 메서드(special method)를 정의해야 합니다.

1. __enter__() 메서드

__enter__() 메서드는 런타임 컨텍스트에 진입할 때 호출됩니다. 이 메서드는 현재 객체(self) 또는 그와 관련된 객체를 반환하며, 반환된 값은 with 문의 as 절에 있는 식별자(identifier)에 바인딩됩니다.

2. __exit__(exc_type, exc_val, exc_tb) 메서드

__exit__() 메서드는 런타임 컨텍스트를 종료할 때 호출되며, 불리언(Boolean) 타입의 결과를 반환합니다. 이 반환값은 예외 발생 여부를 나타냅니다.

  • True 반환: with 문 내에서 예외가 발생했더라도 예외가 외부로 전파되지 않고 정상적으로 처리된 것으로 간주됩니다.
  • False 반환(또는 None): with 문에서 예외가 발생하면 해당 예외가 그대로 전파되며, finally 블록과 유사한 방식으로 마무리 코드가 실행됩니다.

예제 코드

아래 예제는 파일을 안전하게 열고 닫는 사용자 정의 컨텍스트 관리자 클래스입니다.

class MyFileManager:
    def __init__(self, fname):
        self.file_name = fname

    def __enter__(self):
        self.myFile = open(self.file_name, 'r')
        return self.myFile

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.myFile:
            self.myFile.close()

with MyFileManager('sampleTextFile.txt') as myFile:
    x = myFile.read()
print(x)

실행 결과

Test File.
We can store different contents in this file
~!@#$%^&*()_+/*-+\][{}|:;"'<.>/,'"]

코드 설명

  1. __init__: 객체 생성 시 파일 이름을 인스턴스 변수로 저장합니다.
  2. __enter__: with 문이 시작되면 파일을 읽기 모드('r')로 열고, 파일 객체를 반환합니다. 이 객체가 as myFile에 바인딩됩니다.
  3. __exit__: with 블록이 끝나면(예외 발생 여부와 무관하게) 파일을 자동으로 닫아 리소스 누수를 방지합니다.

이처럼 컨텍스트 관리자를 직접 구현하면 try-finally 구문 없이도 깔끔하고 안전한 리소스 관리가 가능합니다. 실무에서는 파이썬 표준 라이브러리의 contextlib.contextmanager 데코레이터를 활용하면 제너레이터 기반으로 더욱 간결하게 컨텍스트 관리자를 작성할 수도 있습니다.