- 개요
Context Manager는 원하는 타이밍에 정확하게 리소스를 할당 및 제공, 반환하는 역할을 담당한다
그러나 위의 역할 말고도 Context Manager는 작업을 확장하여 수행하는 것도 가능하다
이번에 알아볼 Context Manager를 통한 작업의 확장은 이전과 마찬가지로 with 메서드를 통해 이뤄지며
Context Manager 클래스 내부에서 정의한 매직 메서드를 통해 동작한다
- 작업의 확장 : 작업 시간을 출력하는 타이머 Context Manager
import time
class ExecutionWithTimer(object):
def __init__(self, msg):
self.msg = msg
# 작업을 시작하는 시점의 시간 저장
def __enter__(self):
# time.monotonic : 시간을 숫자형으로 반환
self._start = time.monotonic()
return self._start
# __exit__ 매직 메서드가 호출되는 시점은 작업을 종료하는 시점
# (작업을 종료하는 시점의 시간 - 작업을 시작하는 시점의 시간)의 값을 반환하여 순수하게 작업한 시간을 반환
def __exit__(self, errorType, errorValue, errorPoint):
if(errorType):
print(f"Execption occurred : {errorType} {errorValue} {errorPoint}")
return False
else:
print(f"{self.msg} : {time.monotonic() - self._start}")
return True
ExecutionWithTimer 클래스는 Context Manager 클래스로서,
이전의 파일과 관련한 동작이 아닌 작업과 연관되어 있으므로 최상위 객체인 object를 인자로 받아 동작한다
생성자에서는 msg를 인자로 받아 클래스의 msg 프로퍼티를 설정한다
작업이 시작되는 시점에서 호출하는 __enter__ 메서드에서는
time 모듈의 monotonic 함수를 사용하여 __enter__ 메서드를 호출하는 시점을 기록한다
기록한 값을 _start 프로퍼티에 저장하고 반환한다
작업이 완료되는 시점에서 호출하는 __exit__ 메서드에서는
에러가 발생하면 에러의 타입 / 에러의 값 / 에러가 발생한 위치를 출력하고 False를 리턴한다
에러가 발생하지 않았다면 msg 프로퍼티와 순수하게 작업한 시간을 출력하고 True를 리턴한다
- 실제 사용 (1)
with ExecutionWithTimer("Total time for execution") as ce:
print(f'Received Start at {ce}')
for i in range(30000000):
pass
Context Manager 클래스를 통해 작업하기 위해서는 with 메서드에서 사용해야 한다
생성자에 Total time for execution 문자열을 넘겨주어 msg 프로퍼티를 설정한다
이후 __enter__ 메서드가 호출되는 시점의 시간을 출력하고
30000000의 루프를 돈 후 __exit__ 메서드가 호출되므로 최종 작업시간이 출력된다

최종 실행 결과는 위와 같다
작업이 시작된 시점과 순수하게 작업한 시간이 출력되었다
- 실제 사용 (2)
with ExecutionWithTimer("Total time for execution") as ce:
print(f'Received Start at {ce}')
for i in range(30000000):
pass
raise Exception("Forced Error")
이번에는 고의적인 예외를 발생시켜 결과를 확인한다
예외의 타입은 Exception으로, 예외의 값은 Forced Error로 설정하였다

실행 결과는 위와 같다
__enter__ 메서드는 문제없이 동작하였지만,
__exit__ 메서드에서 예외로 인해 로그가 출력되고 있는 것을 확인할 수 있다
'Python > 파이썬 오픈소스 배포' 카테고리의 다른 글
| 언더스코어(_)의 사용 (0) | 2025.06.30 |
|---|---|
| Context Manager Annotation (0) | 2025.06.27 |
| Context Manager (1) (0) | 2025.06.24 |
| 객체의 복사 (0) | 2025.06.23 |
| 람다 함수의 활용 (0) | 2025.06.23 |