2-5. Context Manager (2)

uoayop·2021년 3월 14일
0

Leaf와 Python

목록 보기
9/21
post-thumbnail

2-4 에서 배웠던 내용을 응용해서, 타이머를 만들고, 오류를 발생시켜 보자.


context manager

  • 오늘의 키워드
    • 타이머 클래스 : 수행 시간 측정 가능 , context lib 구현

2-4 복습

" 그래서 context manager가 뭐죠? 🤔 "

파일을 입출력하거나 외부의 connection이 있을 때 한정된 하드웨어 자원 (ex.서버) 을 고려해야 한다.
자원이 제때 반환 되지 않으면 운영이 느려지고, 예외 또한 발생할 수 있다.
그럴 때 자원 회수를 제때 해주기 위해 파이썬에서는 with 문을 제공한다.

우리가 이런 with 문의 구조를 분리하고, 재조립해서 특정 자원을 원하는대로 관리할 수 있다.
이걸 context manager라고 생각하면 되겠다.


타이머 cm 구현하기

  1. 클래스 먼저 구현해주자
  • __init__ 메소드 구현하기
    어떤 작업의 시간을 측정하는지 이름을 입력받으려고 한다. init 메소드의 인자로 msg를 넣어주고, 클래스 내부 변수로 선언해주었다.
class ExecuteTimer(object):
    def __init__(self, msg):
        self._msg = msg
  • __enter__ 메소드 구현하기
    with 구문에 들어갈 때부터 시간을 측정하려고 한다. 따라서 time 모듈을 import 해주고, time.monotonic()으로 현재 시간을 start 변수에 넣어주었다.
    def __enter__(self):
        self._start = time.monotonic()
        return self._start
  • __exit__ 메소드 구현하기
    with 구문이 끝날 때 시간 측정도 종료되야 한다.
    따라서 예외가 발생하지 않았을 때만 측정된 시간이 출력되도록 해주었다.
     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문이 잘 끝났다는 뜻으로 예외 처리를 조금 더 엄격하게 처리할 수 있다.

예외와 에러의 차이

  • 예외 : 프로그래밍적으로 발생, 예외처리 가능하다.
  • 에러 : 정전, 하드디스크 고장 등 물리적으로 고장이 나서 프로그래밍이 정상적으로 동작하지 않는다.
  1. with 구문 선언하기
# '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
  1. 전체 코드
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)

profile
slow and steady wins the race 🐢

0개의 댓글