[Python]Context Manager

파이썬의 Context Manager : 원하는 타이밍에 리소스를 할당/반환하는 역할

  • 클래스를 사용하는 방법
"""
Context Manager
Keyword = Contextlib, __enter__, __exit__, exception
"""

# Context Manager : 원하는 타이밍에 리소스를 할당/반환하는 역할
# 대표적인 구문 : with

# 예1
file = open('./testfile1.txt', 'w')

try:
    file.write('Context manager Test\nTest')
finally:
    file.close()


# 예2
with open('./testfile2.txt', 'w') as f:
    f.write('Context manager Test\nTest')

# 예3
class MyFileWriter():
    def __init__(self, file_name, method):
        print('MyFileWriter started : __init__')
        self.file_obj = open(file_name, method)

    def __enter__(self):
        print('MyFileWriter started : __enter__')
        return self.file_obj

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('MyFileWriter started : __exit__')
        if exc_type:
            print(f'Logging exception {exc_type}, {exc_val}')
        self.file_obj.close()


with MyFileWriter('./testfile3.txt', 'w') as f:
    f.write('Context manager Test\nTest222')
"""
MyFileWriter started : __init__
MyFileWriter started : __enter__
MyFileWriter started : __exit__
"""

# Contextlib : Measure execution(타이머) 제작
import time

class ExecuteTime:
    def __init__(self, msg):
        self._msg = msg

    def __enter__(self):
        self._start = time.monotonic()
        return self._start

    def __exit__(self, exc_type, exc_val, exc_tb):
        if exc_type:
            print(f"Loggin exception {exc_type}, {exc_tb}")
        else:
            print(f'{self._msg} : {time.monotonic() - self._start}')
        return True


with ExecuteTime("테스트 중입니다.") as v:
    print(f'시작  : {v}')
    for i in range(1, 10_000_000):
        pass
    # raise Exception("예외 강제 발생")

"""
시작  : 0.023580708
테스트 중입니다. : 0.19001125
"""

  • 데코레이터를 사용하는 방법
"""
Context Manager Annotation
@contextlib.contextmanager, __enter__, __exit__
"""

# Contextlib 데코레이터 사용

# 예1
import contextlib
import time


@contextlib.contextmanager
def my_file_writer(file_name, method):
    f = open(file_name, method)
    yield f  # __enter__
    f.close()  # __exit__


with my_file_writer('testfile4.txt', 'w') as f:
    f.write('Context manager test4\n Context Lib.')


# 예2
@contextlib.contextmanager
def get_execute_time(msg):
    start = time.monotonic()
    try:  # __enter__
        yield start
    except BaseException as e:
        print(f'Logging Exception: {msg}, {e}')
    else:  # __exit__
        print(f'{msg} 소요시간 : {time.monotonic() - start} s')


with get_execute_time("test") as t:
    print(f'시작시각 : {t}')

    for i in range(40_000_000):
        pass
    # raise ValueError("error");

You may also like...

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다