monstro 2025. 6. 24. 12:11
728x90
반응형

- 개요

컴퓨터에서 사용할 수 있는 리소스는 제한적이므로 리소스를 조절하며 사용해야 할 필요가 있다

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

 

위와 같이 파일을 쓰기 모드로 열어 놓은 경우 close 함수를 통해 닫지 않으면 

컴퓨터는 지속적으로 리소스를 사용하는 누수 현상이 발생하고 끝내 크래시를 내고 만다

 

이런 상황에서 사용하는 것이 바로 Context Manager이다

Context Manager 원하는 타이밍정확하게 리소스를 할당제공, 반환하는 역할을 한다

 

따라서 파이썬에서 Context Manager를 어떤 방식으로 제공하고,

또 사용자가 어떤 방식으로 Context Manager를 설계할 수 있는지 알아본다

 

1) 기초적인 Context Manager

file = open('./testfile1.txt', 'w')
try:
    file.write('Context Manager Test1\nContextlib Test1.')
finally:
    file.close()

 

위와 같이 가장 기초적인 Context Manager를 작성하였다

open 함수를 통해 파일을 쓰기 모드로 열고,

try - finally 구문을 통해 연 파일에 쓰고 닫게 된다

 

2) 개선한 Context Manager

with open('./testfile2.txt', 'w') as f:
    f.write('Context Manager Test2\nContextlib Test2.')

 

1)의 Context Manager를 with 함수를 통해 개선할 수 있다

따로 close 함수를 호출하여 닫지 않아도 리소스는 with 함수의 scope내에서만 유효하다

 

3) 사용자 정의 Context Manaer 클래스

class MyFileHandler():
    def __init__(self, file_name, method):
        print('MyFileHandler started : __init__')
        self.file_obj = open(file_name, method)

    def __enter__(self):
        print('MyFileHandler enter : __enter__')
        return self.file_obj

    def __exit__(self, exc_type, value, trace_back):
        print('MyFileHandler started : __exit__')
        if exc_type:
            print(f'Logging Execption {exc_type} {value} {trace_back}')
        self.file_obj.close()

 

새로운 클래스 MyFileHandler를 생성하였다

해당 클래스는 용자 정의 Context Manager로서 동작한다

 

총 3개의 Magic 메서드(또는 Special 메서드)를 사용하는데,

해당 메서드들은 2개의 언더스코어 쌍을 사용하여 정의하고

어떤 인스턴스가 초기화될 때 Python에서 정한 규칙대로 호출되는 메서드를 의미한다

 

첫번째로 사용하는 __init__ 메서드는 클래스를 사용하는 경우 반드시 필요한 생성자를 의미한다

해당 메서드에서는 로그를 남기고 인자로 받은 파일의 이름과 모드를 사용하여 파일을 open한다

 

두번째로 사용하는 __enter__ 메서드open한 파일을 리턴하는 용도로 사용한다

 

세번째로 사용하는 __exit__ 메서드 open한 파일을 close하는 용도로 사용한다

이때 예외를 의미하는 exc_type인자가 true인 경우 로그를 찍는데,

로그에예외 클래스 / 예외가 발생했을 때 전달된 값 / 예외가 발생한 위치를 남긴다

이후 open한 파일을 close한다

 

4) Context Manager 클래스 사용

with MyFileHandler('./testfile3.txt', 'w') as f:
    f.write('Context Manager Test3\nContextlib Test3.')

 

실제 사용은 위와 같이 진행한다

Context Manager 클래스를 with 함수에서 사용하고 write 함수에 작성할 내용을 넣어준다

 

 

최종 실행 결과는 위와 같다

728x90
반응형