with~as 구문을 사용하는 방법인데, 이게 아마도 고대의 유물인 Lisp 같은 언어에서는 쓰는 매크로 형태와 비슷한 구문입니다. (with-open-file 같은 구문)
with open('filename.txt','w') as f:
blabla..
대략 이런식으로 사용합니다.
기존에 file processing을 하는 경우 open -> context -> close 형태로 사용하고,
이중에 file open 이 fail 되었을 경우 등등 예외처리를 해주었는데,
아무래도 실제 본질 보다는 파일 access이런게 제대로 되었는지에
신경을 쓸 수 밖에 없고 이런부분이, 생각의 흐름을 방해하는 요소중의 하나였는데
이 context manager를 사용하는 경우,
이런 예외처리 부분들이나, with로 ,, 생각의 흐름을 방해하지 않게,
상당히 간략하게 표현이 됩니다.
또 이런 부분들이, 아래와 같이,,
__enter__ ,
__exit__ (self, type, value, traceback) # 예외 발생시 처리 하는 인자들,
함수들을 override하여서, 아래와같이 class안에서 구현이 가능하기도 하고,
class Logger(object):
__enter__(self):
''' enter process '''
__exit__(self, type, value, traceback):
''' exit process '''
아래와 같이 단순 function에 decorator 형태로 @contextmanager 를 함수위에 추가하여
context manager를 추가할 수 도 있습니다.
@contextmanager
def log:
try:
''' log file open and process '''
finally:
''' log file close process '''
이 with 구문의 사용은 주로 file ,socket, db access 라든지 login process 등등에서 활용이 가능하고, 이 with 구문의 활용은 사실 무궁무진합니다
그렇지만 그중에서도 결국 가장 많이 사용하는 부분은 File I/O에서 일텐데,
이중에 동시에 파일을 열고 닫는 경우은 아래와 같은식으로도 사용이 가능합니다
예를 들면,
with open("file1", "r") as src:
with open("file2", "w") as dst:
dst.write(src.read())
이렇게 사용할 수도 있지만, 위와 같이 동시에 사용하는 것 보다는
아래와 같이 하나의 statement로 묶는 것이 좀더 간결해보입니다.
with open("file1", "r") as src, open("file2", "w") as dst:
dst.write(src.read())
즉. 위와 같은 한 문장으로 동시에 여는 형태로 사용할 수도 있습니다.