본문 바로가기

About/Python

[Python] Context Manager(컨텍스트 관리자)

Context Manager

컨텍스트 매니저는 원하는 타이밍에 정확하게 리소스를 할당하고 제공하는 역할을 합니다.

보통 리소스 관리와 관련하여 Context Manager를 자주 사용합니다. 일단 파일을 열면 파일 디스크립터의 누수(resource leak)을 막기 위해 작업이 끝나면 적절히 닫히길 기대합니다. 또는 서비스나 소켓에 대한 연결을 열었을 때도 적절히 닫거나 임시 파일을 제거하는 등의 작업을 해야합니다.

위와 같은 경우에 일반적으로 할당된 모든 리소스를 해제해야 합니다. 모든 것이 잘 처리되었을 경우의 해제는 쉽지만 예외가 발생하거나 오류를 처리해야 하는 경우 모든 조합과 실행 경로에 대하여 처리하는 것은 쉽지 않습니다.

이 때 일반적으로 finally 블록에 정리 코드를 넣는 방법이 있습니다.

fd = open(filename)
try:
    do_something(fd)
finally:
    fd.close()

 

하지만 가장 많이 사용되는 컨텍스트 매니저는 with 문입니다.

with 문(PEP-343)

위와 같은 코드를 with 문을 이용하여 파이썬스럽게 구현할 수도 있습니다.  

with open(filename) as fd:
    do_something(fd)

 

with 문(PEP-343)은 컨텍스트 관리자로 진입하게 합니다. 이 경우 open 함수는 컨텍스트 관리자 프로토콜을 구현되며 예외가 발생한 경우에도 블록이 완료되면 파일이 자동으로 닫히게 됩니다.

컨텍스트 관리자는 __enter____exit__ 두 개의 메서드로 구성됩니다. 위의 코드에서 with 문은 __enter__ 메서드를 호출하고 이 함수가 무엇을 반환하든 as 이후에 지정된 변수(fd)에 할당됩니다. 꼭 __enter__ 메서드가 특정한 값을 반환할 필요는 없으며, 값을 반환하더라도 필요가 없다면 변수에 할당하지 않아도 됩니다.

해당 라인이 실행되면 다른 파이썬 코드가 실행될 수 있는 새로운 컨텍스트로 진입합니다. 그리고 해당 블록에 대한 마지막 문장이 끝나면 컨텍스트가 종료되며 컨텍스트 관리자 객체의 __exit__ 메서드를 호출하게 됩니다.

컨텍스트 관리자 블록 내에 예외 또는 오류가 발생하는 경우에도 __exit__ 메서드가 호출되므로 예외 상황에 대하여 안전하게 실행하는데 편하다는 장점이 있습니다. 또한 __exit__ 메서드에서 예외가 발생한 경우 해당 예외를 파라미터로 받기 때문에 임의의 방법으로 처리할 수도 있습니다.

컨텍스트 관리자가 리소스 관리에만 사용 가능한 것은 아닙니다. 블록의 전후에 필요로 하는 특정 논리를 제공하기 위해 자체 컨텍스트 관리자를 구현할 수도 있습니다. 따라서 컨텍스트 관리자는 관심사를 분리하고 독립적으로 유지되어야하는 코드를 분리하는 좋은 방법입니다. 컨텍스트 관리자를 잘 사용하면 로직을 관리하기가 더 쉬워질 것입니다.

Class로 컨텍스트 관리자 구현

최소한 컨텍스트 매니저는 __enter__ __exit__메소드를 가지고 있습니다. 파일을 여는 컨텍스트 매니저 Class를 생성하고 사용해보겠습니다.

class MyFile(object):
    def __init__(self, file_name, method):
        self.fd = open(file_name, method)

    def __enter__(self):
        return self.fd

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.fd.close()

with MyFile('temp.txt', 'wb') as opened_file:
    opened_file.write('Hello!')

 

위의 코드는 다음과 같은 순서로 실행됩니다.

1. MyFile 클래스의 __init__()이 호출되며 open 함수로 파일을 읽어옴
2. __enter__ 메서드의 반환 값으로 파일 객체 반환되며 Context에서 opened_file라는 변수에 저장됨
3. opened_file 파일 객체의 write() 함수가 호출되며 파일에 "Hello!"가 쓰여짐
4. Context 내의 모든 코드가 실행되었으므로 __exit__()이 호출되며 파일 객체가 닫힘 - fd.close()

 


Python의 Context Manager에 대하여 알아보았습니다.

출처

https://ddanggle.gitbooks.io/interpy-kr/content/ch24-context-manager.html

 

컨텍스트 매니저(context manager) · interpy-kr

 

ddanggle.gitbooks.io

http://www.yes24.com/Product/Goods/69064790

 

파이썬 클린 코드 - YES24

견고하면서도 확장성이 뛰어난 파이썬 코드를 만드는 비법파이썬은 누구나 쉽게 시작할 수 있는 프로그래밍 언어이다. 그러나 이 책에서 소개하는 다음 내용을 제대로 숙지하지 않고 개발을 하

www.yes24.com