본문 바로가기

파이썬 with란?

파이썬 with 문법 완벽 정리 – 자동으로 리소스를 관리하는 방법

파이썬 코드를 보다 보면 with라는 키워드를 종종 보게 된다. 특히 파일을 열거나 데이터베이스를 연결할 때 자주 등장하는데, 이게 뭔지 잘 모르면 그냥 신기한 문법처럼만 보일 수 있다.

 

사실 with는 파이썬에서 리소스를 안전하게 다루기 위한 도구다.

 

파일을 열고 닫을 때 open()과 close()를 쓰는 게 일반적인데, with를 쓰면 이런 과정을 자동으로 처리해준다. 그래서 코드가 깔끔해지고, 실수도 줄어든다.

조금 더 정확히 말하면, with는 컨텍스트 매니저(Context Manager)라는 개념을 기반으로 동작한다.

 

 

 

어떤 작업이 시작되고 끝날 때 자동으로 특정 동작을 해주는 방식인데, 주로 파일, DB, 네트워크, 락(lock) 같은 자원 관리에 쓰인다.

 

 

기본 문법

with open('파일경로', 'r') as 파일객체:
    코드블록

예를 들어 위 코드는 파일을 열고 읽거나 쓰는 작업을 한 뒤, 자동으로 `close()`까지 해준다. 중간에 오류가 나더라도 자동으로 닫힌다. 이게 진짜 편하다.

1. 텍스트 파일 읽기

with open('example.txt', 'r', encoding='utf-8') as f:
    data = f.read()
    print(data)

`with` 덕분에 `f.close()`를 따로 안 써도 된다. 파이썬이 자동으로 닫아주니까.

2. 파일에 내용 쓰기

with open('output.txt', 'w') as f:
    f.write("Hello, world!")

파일을 열고 문자열을 쓰고, 자동으로 닫는다. 정말 직관적이다.

3. 여러 파일 동시에 사용

with open('in.txt') as fin, open('out.txt', 'w') as fout:
    fout.write(fin.read())

파일 두 개를 동시에 열고 작업할 수 있다. 이때도 각각 알아서 닫힌다.

4. 직접 만든 클래스에 with 적용

class MyContext:
    def __enter__(self):
        print("시작")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("끝")

with MyContext():
    print("작업 중")

이처럼 `__enter__()`와 `__exit__()`를 구현하면 내가 만든 클래스도 `with` 문에 쓸 수 있다.

요약

파이썬의 `with` 문은 파일, 네트워크, DB 등 리소스를 다룰 때 실수를 줄이고 코드를 깔끔하게 해준다. 자동 정리가 핵심이다. 초보자일수록 꼭 익혀야 하는 문법 중 하나다.

 

 

예제 1. 텍스트 파일 읽기

with open('example.txt', 'r', encoding='utf-8') as f:
    content = f.read()
    print(content)

텍스트 파일을 열고 내용을 읽은 뒤 자동으로 닫는다. 가장 기본적인 사용 예다.

 

예제 2. 파일에 텍스트 쓰기

with open('log.txt', 'w') as f:
    f.write("로그 기록 시작")

파일을 쓰기 모드로 열고 문자열을 기록한다. 작업이 끝나면 자동으로 저장 및 닫힘.

 

예제 3. 여러 파일 동시 사용

with open('source.txt', 'r') as src, open('copy.txt', 'w') as dest:
    dest.write(src.read())

두 파일을 동시에 열고, 한 파일에서 읽은 내용을 다른 파일에 복사한다.

 

예제 4. 예외 처리와 함께 사용

try:
    with open('config.json') as f:
        config = f.read()
except FileNotFoundError:
    print("설정 파일이 없습니다.")

파일이 없을 경우 오류를 잡아내고, 프로그램이 멈추지 않도록 한다.

 

예제 5. 사용자 정의 context manager

class Timer:
    def __enter__(self):
        import time
        self.start = time.time()
        return self

    def __exit__(self, *args):
        import time
        print(f"총 소요 시간: {time.time() - self.start:.2f}초")

with Timer():
    sum = 0
    for i in range(1000000):
        sum += i

작업 시간 측정을 위해 직접 context manager 클래스를 만들어서 사용한 예시다.