Python - with, context manager에 대한 이해.

Language/Python 2019. 11. 16. 22:04 posted by TechNote.kr


 특정 구문을 시작 전후 반드시 실행해야 하는 구문이 있다면 Python에서는 어떻게 구현할 것인가.
일반적인 코드로 구현하자면 다음과 같다. 
 

print("->> Before routine") 
routine1()
print("<<- After routine") 

print("->> Before routine") 
routine2()
print("<<- After routine") 

print("->> Before routine") 
routine3()
print("<<- After routine") 

 

만약 "After routine" 루틴을 반드시 타야하는 경우라면 RoutineX 함수에서 exception 등이 발생하면 문제가 생길 수 있다. 이 때는 아래와 같이 작성 가능할 것이다. 

 

print("->> Before routine") 
try:
	routine1()
finally:
	print("<<- After routine") 

print("->> Before routine") 
try:
	routine2()
finally:
	print("<<- After routine") 

print("->> Before routine") 
try:
	routine3()
finally:
	print("<<- After routine") 

 

하지만 with 구문을 통해 context manager object 를 사용한다면 try ~ finally 구문을 사용하지 않고도 더 관리하기 좋은 코드를 작성할 수 있다. 

 

class routine_process: 
    def __enter__(self): 
        print("->> Before routine") 

    def __exit__(self, type, value, traceback): 
        print("<<- After routine") 

with routine_process(): 
    routine1() 

with routine_process(): 
    routine2()

with routine_process(): 
    routine3()

 

아래와 같이 routineX 내에서 exception 이 발생하더라도 "After routine" 루틴이 정상적으로 수행되는 것을 볼 수 있다. 

 

class routine_process: 
    def __enter__(self): 
        print("->> Before routine") 

    def __exit__(self, type, value, traceback): 
        print("<<- After routine") 

with routine_process(): 
    routine1().split()

with routine_process(): 
    routine2()

with routine_process(): 
    routine3()
user@TechNote:~$ /usr/bin/python3 /home/user/with.py
->> Before routine
Routine1()
<<- After routine
Traceback (most recent call last):
  File "/home/user/with.py", line 9, in <module>
    Routine1().split()
AttributeError: 'NoneType' object has no attribute 'split'

 

 

Reference


https://www.python.org/dev/peps/pep-0343/