Python에서 자원을 읽고 쓸 때, try-except 문을 사용하지 않고 with문을 사용한다고 한다.
try-except 문을 사용해서 파일을 읽고 쓰게 되면, finally에서 연결 끊는 코드를 안해주면 자원을 계속 실행하고 있게된다. 직접 해제해줘야함.
f = open('file.txt', 'r')
try:
data = f.read()
print(data)
finally:
f.close() # 리소스를 직접 해제해야 함
with문을 사용하면 block을 벗어나면 f.close를 안해줘도 자동으로 연결을 해제해준다.
with open('file.txt', 'r') as f:
data = f.read()
print(data)
# with 블록을 벗어나는 순간, f.close()가 자동으로 호출됨
📌 이렇게 가능한 이유가 뭘까?
일단, with문은 __enter__와 __exit__라는 특별한 메서드를 호출하도록 설계된 문법이다.
해당 내용은 Python 공식 문서에서 확인이 가능하다.
PEP 343 – The “with” Statement | peps.python.org
This PEP adds a new statement “with” to the Python language to make it possible to factor out standard uses of try/finally statements.
peps.python.org
📌 Context Manager란?
Context Manager는 __enter__()와 __exit__()를 제공한다. 그리고 open()는 ContextManager 프로토콜을 따르는 객체를 반환해준다.
open() 반환하는 객체 TextIOWrapper -> TextIOWrapper는 TextIOBase를 상속받고 있고 해당 객체는 _io._IOBase를 상속받고 있다.
타고타고 들어가서 _io._IOBase 객체를 가보면 __enter__와 __exit__가 존재한다.
_io._IOBase라는 추상 클래스가 컨텍스트 매니저 프로토콜을 구현하고 있는 형태.
io.IOBase — Python Standard Library
tedboy.github.io
class TestContextManager:
def __init__(self):
print("__init__")
def __enter__(self):
print("__enter__")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("__exit__")
t = TestContextManager()
print("="*10)
with TestContextManager() as t:
print("__with__ start")
print("="*10)
# __init__
# ==========
# __init__
# __enter__
# __with__ start
# __exit__
# ==========
TestContextManager 객체를 단독으로 선언해줬을때는 __init__만 호출되고,
with문과 같이 선언해줬을때는 __init__ 메소드와 함께 __enter__, __exit__ 도 호출된다.
오히려, __enter__, __exit__ 구현안되어있는 객체를 with문과 객체를 생성할 때는 AttributeError: __enter__ 오류가 뜨게된다.
✅ with문은 ContextManager 프로토콜을 따르는 객체와 함께 쓸 수 있음.
✅ 자원을 읽고 쓸 때, with문을 사용하지만 예외처리는 잡을 수 없기때문에 try block안에 with문 포함된 형태로 자원을 불러오는 경우가 많다고함.
Python 프로토콜과 추상클래스에대해서도 공부해야겠다.
contextlib — Utilities for with-statement contexts
Source code: Lib/contextlib.py This module provides utilities for common tasks involving the with statement. For more information see also Context Manager Types and With Statement Context Managers....
docs.python.org
📌 contextlib.contextmanager 데코레이터
ContextManager를 보다보면 contextlib 모듈이 나오는데 이건 ContextManager를 쓰기 쉽게 제공해주는 모듈이다.
클래스 형태가 아닌 함수 형태로도 훨씬 짧게 구현 가능.
from contextlib import contextmanager
@contextmanager
def file_manager(file_name, method):
f = open(file_name, method) # 자원 획득
yield f # with문으로 자원 넘김
f.close() # 자원 해제
with file_manager("text.txt", "w") as f:
f.write("context manager") # 넘겨받은 자원을 사용
contextmanager 데코레이터에는 무조건 yield 키워드는 무조건 들어가야한다.
yield 키워드를 기준으로 위에는 __enter__, 아래는 __exit__로 분리되기 때문이고
yield 키워드가 사용하는 함수의 경우, Generator (제너레이터) 함수라고 한다.
5-2. context manager-2
### context manager 예제 context manager를 이용해서 timer를 만드는 예제를 작성해보자. ``` import time class Timer(o…
wikidocs.net
yield가 뭐길래...? 이건 다음에 Generator(제너레이터)와 따로 정리해보겠다.👋
[Python] Yield 키워드와 Generator 함수
ContextManager를 공부하다가 나온 yield 키워드. [Python] 파일 읽고 쓰기 with문 - ContextManagerPython에서 자원을 읽고 쓸 때, try-except 문을 사용하지 않고 with문을 사용한다고 한다.try-except 문을 사용해서
itstudentstudy.tistory.com
'AI > Python' 카테고리의 다른 글
[Python] Yield 키워드와 Generator 함수 (0) | 2025.10.13 |
---|---|
[Python] 클래스의 던더 변수 및 메소드 (0) | 2025.10.04 |
[Python] 클래스와 변수 + 접근지정자 getter, setter (0) | 2025.10.01 |
[Python] datetime 모듈 (0) | 2025.09.25 |
[Python] ascii code <-> string 변환 방법 (0) | 2025.09.10 |