2-4 에서 배웠던 내용을 응용해서, 타이머를 만들고, 오류를 발생시켜 보자.
" 그래서 context manager가 뭐죠? 🤔 "
파일을 입출력하거나 외부의 connection이 있을 때 한정된 하드웨어 자원 (ex.서버) 을 고려해야 한다.
자원이 제때 반환 되지 않으면 운영이 느려지고, 예외 또한 발생할 수 있다.
그럴 때 자원 회수를 제때 해주기 위해 파이썬에서는 with 문을 제공한다.
우리가 이런 with 문의 구조를 분리하고, 재조립해서 특정 자원을 원하는대로 관리할 수 있다.
이걸 context manager라고 생각하면 되겠다.
__init__
메소드 구현하기class ExecuteTimer(object):
def __init__(self, msg):
self._msg = msg
__enter__
메소드 구현하기time.monotonic()
으로 현재 시간을 start
변수에 넣어주었다. def __enter__(self):
self._start = time.monotonic()
return self._start
__exit__
메소드 구현하기 def __exit__(self, exc_type, exc_value, exc_traceback):
# 발생한 예외가 있을 때, 예외 처리를 해준다.
if exc_type:
print("Logging exception {}".format((exc_type, exc_value, exc_traceback)))
# 예외가 발생하지 않았을 때 측정한 시간을 출력한다.
else:
print('{}:{} s'.format(self._msg, time.monotonic() - self._start))
return True
# if문이 잘 끝났다는 뜻으로 예외 처리를 조금 더 엄격하게 처리할 수 있다.
예외와 에러의 차이
- 예외 : 프로그래밍적으로 발생, 예외처리 가능하다.
- 에러 : 정전, 하드디스크 고장 등 물리적으로 고장이 나서 프로그래밍이 정상적으로 동작하지 않는다.
# 'Start Job' : 시간 측정할 작업의 이름
with ExecuteTimer('Start Job') as v:
print('Received start monotonic : {}'.format(v))
#아래의 작업을 하는 동안 시간을 측정한다.
for i in range(100000000):
pass
# 강제로 에러를 발생 시켜서 예외 처리를 확인해보자
raise Exception('Raise! Exception!!')
# 출력 :
# Received start monotonic : 0.029865607
# Start Job:3.825171315 s
import time
class ExecuteTimer(object):
def __init__(self, msg):
self._msg = msg
def __enter__(self):
self._start = time.monotonic()
return self._start
def __exit__(self, exc_type, exc_value, exc_traceback):
if exc_type:
print("Logging exception {}".format((exc_type, exc_value, exc_traceback)))
else:
print('{}:{} s'.format(self._msg, time.monotonic() - self._start))
return True
with ExecuteTimer('Start Job') as v:
print('Received start monotonic : {}'.format(v))
#excute job
for i in range(100000000):
pass
raise Exception('Raise! Exception!!')
출처: 인프런 - 모두를 위한 파이썬 : 필수 문법 배우기 Feat. 오픈소스 패키지 배포 (Inflearn Original)