with문은 코드가 특별한 컨텍스트 안에서 실행되는 경우 표현
컨텍스트 매니저를 정의하면 함수의 로그 수준을 일시적으로 높임
도우미 함수는 with 블록을 실행하기 직전에 로그 심각성 수준을 높이고, 블록을 실행한 직후에 심각성 수준을 이전 수준으로 회복
from contextlib import contextmanager
@contextmanager
def debug_logging(level):
logger = logging.getLogger()
old_level = logger.getEffectiveLevel()
logger.setLevel(level)
try:
yield #yield식은 with 블록의 내용이 실행되는 부분을 지정
finally:
logger.setLevel(old_level) #이 도우미 함수를 통해서 yield식에 발생될
with와 대상 변수 함께 사용하기
컨텍스트 매니저가 객체 반환
#as대상 변수에게 값을 제공하도록 필요한 yield값 넘기기
@contextmanager
def log_level(level, name):
logger = logging.getLogger(name)
old_level = logger.getEffectiveLevel()
logger.setLevel(level)
try:
yield logger
finally:
logger.setLevel(old_level)
#with 블록 내의 로그 심각성 수준이 낮게 설정되어있기에 디버깅 메시지 출력
#logging모듈을 직접 사용하면 아무 메시지 출력 안됨
with log_level(logging.DEBUG, 'my-log') as logger:
logger.debug(f'대상: {logger.name}!')
logging.debug('이 메시지는 출력되지 않습니다')
with문을 사용하면 try/finally 블록을 통해서 사용해야하는 로직을 재활용하면서 시각적 잡음을 줄일 수 있다.
contextlib 내장 모듈이 제공하는 contextmanager데코레이터를 사용하면 여러분이 만든 함수를 with 문에 사용할 수 있다.
컨텍스트 매니저가 yield하는 값은 with 문의 as부분에 전달되고 이를 활용하면 특별한 컨텍스트 내부에서 실행되는 코드 안에서 직접 그 컨텍스트에 접근할 수 있다.