Menu
Coddy logo textTech

컨텍스트 관리자

Coddy Python 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 64개 중 41번째.

컨텍스트 관리자를 사용하면 리소스가 필요할 때 정확하게 할당하고 해제할 수 있습니다. 또한 오류가 발생하더라도 적절한 정리가 이루어지도록 보장합니다.

다음은 with 문을 사용하는 가장 일반적인 예시입니다:

with open('example.txt', 'w') as file:
    file.write('Hello, world!')
# 파일은 여기서 자동으로 닫힙니다

파일은 예외가 발생하더라도 블록이 끝난 후 자동으로 닫힙니다.

__enter____exit__ 메서드를 구현하여 자신만의 컨텍스트 관리자를 만드세요:

class MyContext:
    def __enter__(self):
        print("Entering the context")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting the context")
        return False  # 예외를 억제하지 않음

커스텀 컨텍스트 관리자를 사용하세요:

with MyContext() as ctx:
    print("Inside the context")

출력:

Entering the context
Inside the context
Exiting the context

데이터베이스 연결을 위한 더 실용적인 컨텍스트 관리자를 만들어 보겠습니다:

class DatabaseConnection:
    def __init__(self, db_name):
        self.db_name = db_name
        self.connection = None
    
    def __enter__(self):
        print(f"Connecting to {self.db_name}")
        self.connection = f"Connection to {self.db_name}"
        return self.connection
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"Closing connection to {self.db_name}")
        self.connection = None

with DatabaseConnection("users_db") as conn:
    print(f"Using {conn}")
    print("Performing database operations...")

컨텍스트 관리자에서 예외 처리하기:

class SafeContext:
    def __enter__(self):
        print("Setting up resources")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Cleaning up resources")
        if exc_type:
            print(f"An exception occurred: {exc_val}")
        return False  # 예외를 억제하지 않음

with SafeContext():
    print("Working with resources")
    # raise ValueError("Something went wrong")  # 테스트하려면 주석을 해제하세요

출력:

Connecting to users_db
Using Connection to users_db
Performing database operations...
Closing connection to users_db
Setting up resources
Working with resources
Cleaning up resources

__exit__ 메서드는 세 개의 매개변수를 받습니다:

  • exc_type: 예외 유형 (또는 None)
  • exc_val: 예외 값 (또는 None)
  • exc_tb: 예외 트레이스백 (또는 None)

핵심 포인트: 컨텍스트 관리자는 __enter____exit__ 메서드를 사용하여 리소스를 관리합니다. with 문은 이러한 메서드를 자동으로 호출하여 적절한 설정과 정리를 보장합니다. 이는 파일, 데이터베이스 연결 및 정리가 보장되어야 하는 기타 리소스에 특히 유용합니다.

challenge icon

챌린지

쉬움

이 챌린지에서는 컨텍스트 블록에 진입하고 종료할 때까지 경과된 시간을 측정하는 컨텍스트 관리자 클래스를 구현합니다.

  • timer.py - Timer 클래스 구현이 포함되어 있습니다 (이 파일을 수정하게 됩니다)
  • driver.py - 포괄적인 테스트 케이스가 포함되어 있습니다 (수정하지 마세요)

TODO 주석에 따라 timer.pyTimer 컨텍스트 관리자를 구현하세요. 클래스는 다음을 수행해야 합니다:

  1. 컨텍스트에 진입할 때 시작 시간을 기록합니다
  2. 종료할 때 종료 시간을 기록합니다
  3. 경과된 시간을 계산하고 표시합니다

치트 시트

컨텍스트 관리자는 리소스가 필요할 때 정확하게 할당하고 해제하여, 오류가 발생하더라도 적절한 정리가 이루어지도록 보장합니다.

자동 리소스 관리를 위해 with 문을 사용하세요:

with open('example.txt', 'w') as file:
    file.write('Hello, world!')
# 파일은 여기서 자동으로 닫힙니다

__enter____exit__ 메서드를 구현하여 사용자 정의 컨텍스트 관리자를 만드세요:

class MyContext:
    def __enter__(self):
        print("Entering the context")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exiting the context")
        return False  # 예외를 억제하지 않음

with MyContext() as ctx:
    print("Inside the context")

__exit__ 메서드는 세 개의 매개변수를 받습니다:

  • exc_type: 예외 유형 (또는 None)
  • exc_val: 예외 값 (또는 None)
  • exc_tb: 예외 트레이스백 (또는 None)

컨텍스트 관리자에서 예외 처리하기:

class SafeContext:
    def __enter__(self):
        print("Setting up resources")
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Cleaning up resources")
        if exc_type:
            print(f"An exception occurred: {exc_val}")
        return False  # 예외를 억제하지 않음

직접 해보기

from timer import Timer
import time

# 테스트 케이스 처리기
test_case = input()

if test_case == "basic_test":
    # 기본 기능 테스트
    with Timer():
        # 작업 시뮬레이션
        time.sleep(2)  # 프로그램을 2초 동안 대기시킵니다.

elif test_case == "nested_contexts":
    # 중첩된 컨텍스트 관리자 테스트
    with Timer():
        time.sleep(1)
        with Timer():
            time.sleep(1)

elif test_case == "exception_handling":
    # 컨텍스트 내 예외 처리 테스트
    try:
        with Timer():
            time.sleep(1)
            raise ValueError("Test exception")
    except ValueError as e:
        print(f"Caught exception: {e}")

elif test_case == "zero_sleep":
    # 최소 대기 시간 테스트
    with Timer():
        time.sleep(0.001)

elif test_case == "multiple_timers":
    # 순차적인 다중 타이머 테스트
    with Timer():
        time.sleep(1)
    
    with Timer():
        time.sleep(0.5)
    
    with Timer():
        time.sleep(2)

elif test_case == "as_decorator":
    # 함수 컨텍스트 내 타이머 테스트
    def timed_function():
        with Timer():
            time.sleep(2)
    
    timed_function()

else:
    # 기본 테스트 - 기본 기능
    with Timer():
        # 작업 시뮬레이션
        time.sleep(2)  # 프로그램을 2초 동안 대기시킵니다.
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

Object Oriented Programming의 모든 레슨