알고쓰면 편한 With 구문

진선용·2026년 4월 19일

처음 프로젝트할때, DBManager라는 클래스를 만들어서 pymysql 라이브러리를 통해 DB에서 데이터를 가져왔었어요.

초기 DBManager 예시 (가독성을 위해 메서드 내용은 제외했습니다.)

import pymysql

class DBManager :
    def __init__(self) :
   
    # DB연결
    def DBOpen(self) :
  
    # DB연결 종료
    def DBClose(self):

위 코드 처럼 메서드를 만들면 DB에서 데이터를 꺼내올때마다 DBOpen();을 적어줘야하고 메모리 누수(Memory Leak) 방지하기 위해 DBClose(); 를 적어줘야하는 불편함이 있었어요.

이 불편함을 해결하기 위한 구문이 바로 with 라는 구문이에요! with 구문을 사용하기 위해서는 먼저, '컨텍스트 매니저(context manager)'에 대해 알아야해요!

컨텍스트 매니저란 "작업 수행 전 setup과 작업 종료 후 teardown을 '자동'으로 처리하기 위해, __enter____exit__ 메서드를 구현한 컨텍스트 매니저 객체"에요.
(메서드 명에서 알 수 있듯이 __enter__에서 setup 이 실행되고 __exit__에서 teardown이 실행됩니다.)

with 구문이 바로 컨텍스트 매니저를 실행하는 문법이에요!

컨텍스트 관리 프로토콜(Context Management Protocol)을 구현한 클래스

import pymysql

class DBManager :
    def __init__(self) :
   
    # setup
    def __enter__(self) :
   
    # teardown
    def __exit__(self, exc_type, exc_val, traceback):

먼저 DBManager에 __enter__, __exit__ 메서드를 만들어줘야 합니다. 또한, exit 메서드를 보시면 매개변수가 3개가 더 늘어난 것을 알 수 있는데,
• exc_type : 발생한 예외의 클래스 타입
• exc_val : 발생한 예외의 객체
• traceback : 예외가 발생한 위치 정보가 담긴 traceback 객체
exit 메서드로 위 3개의 값이 들어오기 때문에 매개변수를 3개 더 작성하지 않으면 에러가 나면서 작동하지 않아요.

with 구문을 사용하는 DAO 클래스

from [파일이름] import DBManager

class testDAO :
    def test() :
        with DBManager() as dbms :        	

DAO 클래스안의 메서드안에 위 예시코드처럼 with 구문을 사용하면 됩니다.

이렇게 with 구문을 사용하면 정상적으로 코드가 끝나든 에러로 구문이 끝나든 알아서 teardown을 작동해주기 때문에 누락이나 오타로 인한 메모리 누수를 방지할 수 있어요!

+ 사용할 객체가 컨텍스트 관리 프로토콜을 따르는 객체인지 알고싶을때는 dir() 함수를 사용해서 __enter__, __exit__ 함수가 있는지 확인하여 알 수 있습니다.

테스트 스크립트 (정상 작동 시)

테스트 스크립트 (에러 발생 시)

traceback 같은 경우 따로 에러체크를 하지 않았습니다. traceback은 위에서 설명드렸듯이 에러가 발생한 상세경로를 알려주기 때문에 정보량이 많고 대부분의 경우 필요로 하지 않기 때문에 제 경우에서도 사용하지 않았습니다.


이번 공부를 하면서 DB Connection pool이란 것도 알게됐는데 이 다음 단계인 것 같더라고요? 다음에 시간내서 공부해볼까 합니다. :D

profile
최적의 해답을 찾고 무한한 과정을 즐기는 개발자

0개의 댓글