Remarks
이 글은 전문가를 위한 파이썬(Fluent Python)을 정리한 자료입니다.
1. Context manager
__enter__()
,__exit()__
을 구현하여 context manager를 생성할 수 있다.import traceback as tb from types import TracebackType class ExceptionHandler: def __init__(self, exit_return_value): self.exit_return_value = exit_return_value def __enter__(self): return self def __exit__(self, exc_type: type | None, exc_value: Exception | None, traceback: TracebackType | None): if exc_type is ZeroDivisionError: print(tb.format_exc()) return self.exit_return_value
__exit__()
은 exception에 대한 정보를 입력값으로 받는다.exc_type
- 예외 발생 X:
None
- 예외 발생 O: Exception type
- 예외 발생 X:
exc_value
- 예외 발생 X:
None
- 예외 발생 O: Exception
- 예외 발생 X:
traceback
- 예외 발생 X:
None
- 예외 발생 O: traceback 객체. 이것보다
traceback
패키지 임포트해서traceback.format_exc()
사용하는 게 낫다.
- 예외 발생 X:
__exit__()
의 return값이True
이외의 값을 반환하면with
블록에서 발생한 예외가 상위 코드로 전달된다.
True
를 반환해서 예외가 처리되었음을 파이썬 인터프리터에 알려주자.with ExceptionHandler(True): 1/0 Traceback (most recent call last): File "/tmp/ipykernel_1487515/3039134459.py", line 2, in <module> 1/0 ~^~ ZeroDivisionError: division by zero
with ExceptionHandler(False): 1/0 Traceback (most recent call last): File "/tmp/ipykernel_1487515/828479559.py", line 2, in <module> 1/0 ~^~ ZeroDivisionError: division by zero --------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) Cell In[92], line 2 1 with ExceptionHandler(False): ----> 2 1/0 ZeroDivisionError: division by zero
2. @contextmanager
- class로 context manager를 생성하는 대신, decorator를 이용하면 간단하게 구현이 가능하다.
import contextlib @contextlib.contextmanager def looking_glass(): import sys original_write = sys.stdout.write def reverse_write(text): original_write(text[::-1]) sys.stdout.write = reverse_write msg = "" try: yield 'JABBERWOCKY' except Exception as e: msg = f"Unexpected exception occurs: {e}" finally: sys.stdout.write = original_write if msg: print(msg)
yield
문 앞에 있는 코드는__enter__()
를 호출할 때 실행되고,yield
문 뒤에 있는 코드는__exit()__
이 호출될 때 실행된다.with
블록 안에서 예외가 발생하면 시스템이 불안정한 상태로 남게되는 것을 방지하기 위해 예외처리가 필요하다.
PREVIOUSEtc