기존 파이썬 코드에서는 파일, 네트워크 소켓, DB 커넥션 등 자원 사용 후 수동으로 정리(닫기)해야 했습니다. 이를 위해 try-finally 블록을 사용했지만, 매번 이런 보일러플레이트를 작성하는 것은 번거롭고, 예외 발생 시 자원 반납 처리 누락 등의 문제가 생기기 쉬웠습니다.
Context Manager와 with
문을 사용하면 이러한 자원 정리 과정을 자동화하고, 코드 가독성과 안전성을 크게 향상시킬 수 있습니다.
이번 글에서는 기존 방식과 새로운 방식의 비교, Context Manager 개념, with
문 사용 예제, 장단점을 살펴봅니다.
이전에는 어떻게 했을까?
try-finally를 통한 수동 자원 정리
f = open("data.txt", "r")
try:
content = f.read()
finally:
f.close()
- 장점: 명시적으로 자원 사용 범위를 알 수 있음
- 단점: 매번 try-finally 패턴 반복, 예외 처리 로직과 자원 반납 로직 혼재
Context Manager와 with문 도입
with
문은 Context Manager 프로토콜(__enter__
, __exit__
)을 지원하는 객체를 사용할 때, 진입 시 __enter__()
가 호출되고, 블록 종료 시(정상/예외 여부와 무관하게) __exit__()
가 호출되어 자원을 자동 정리합니다.
with open("data.txt", "r") as f:
content = f.read()
장점:
- 보일러플레이트 감소: try-finally 없이도 자원 정리 자동 처리
- 가독성↑: 자원 사용 범위가
with
블록으로 명확히 구분 - 안전성↑: 예외 발생 시에도 exit가 호출되어 자원 반납 보장
커스텀 Context Manager 구현
직접 만든 클래스에도 __enter__
, __exit__
메서드를 정의하면 with
문에서 사용 가능. 예:
class ManagedResource:
def __enter__(self):
print("Resource acquired")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("Resource released")
with ManagedResource() as resource:
print("Using resource")
출력:
Resource acquired
Using resource
Resource released
예외 발생 시에도 __exit__
호출, 자원 정리 보장.
단점/주의사항
- Context Manager는 자원 사용 범위를 명확히 제한하므로, 자원을 블록 밖에서 계속 사용하려면 별도 구조 고려 필요
- 모든 상황에
with
문이 적합한 것은 아니지만, 파일, 소켓, 락(lock), DB 커넥션 등 자원 사용 후 반납 필요 시 적합 - Python 2에서는 contextlib 모듈의 contextmanager 데코레이터로 유사 기능 구현 가능, Python 3+에서 기본 지원
결론
- 이전 방식: try-finally로 자원 정리, 보일러플레이트 증가, 예외 처리 시 코드 복잡
- 새로운 방식: Context Manager와
with
문으로 자원 반납 자동화, 가독성↑, 안정성↑ - Pythonic하게 자원 관리 로직 단순화 가능
다음 글에서는 표준 라이브러리의 고급 함수나 도구(functools
, itertools
)를 통해 수작업 루프보다 더 간결하고 선언적으로 데이터를 처리하는 방식에 대해 알아보며, 코드 단순화와 성능 개선에 유용한 함수형 툴들을 살펴보겠습니다.
반응형
'개발 이야기 > Python (파이썬)' 카테고리의 다른 글
[모던 Python 10편] 시리즈 마무리 및 추가 학습 방향 (0) | 2024.12.17 |
---|---|
[모던 Python 9편] functools, itertools로 선언적 데이터 처리하기 (0) | 2024.12.17 |
[모던 Python 7편] 패턴 매칭(Pattern Matching)으로 조건문 단순화하기 (0) | 2024.12.17 |
[모던 Python 6편] pyproject.toml와 Poetry로 패키징 현대화하기 (0) | 2024.12.17 |
[모던 Python 5편] concurrent.futures, asyncio로 동시성/병렬 코드 간소화하기 (0) | 2024.12.17 |