Python : 컨텍스트 관리자, with <객체> as <변수명>
file을 오픈할 때 쓰는 with <객체> as <변수명> 구문. 보통 파일을 오픈한 뒤 자동적으로 close 해주는 구문으로 알고 있는데, 이 기능 하나만 가지고 이런 구문이 생겼을거라 생각되지 않아 추가적으로 찾아보게 되었다.
결론적으로 말하면 file을 오픈할 때만 쓰는 것이 아닌 쓰레드를 락인해놓고 자동적으로 푼다거나 데이터베이스 연결을 한 뒤 자동적으로 닫거나 하는 경우처럼 사용 뒤에 자동적으로 무언가 나가거나 끌 필요가 있을 때 사용된다는 걸 알게 되었다.
with <객체> as <변수명>
객체가 중간에 나와서 당황했지만 흔히 쓰는 파일 오픈을 위해 open()을 쓰는 경우는 open()의 결과로 file 객체가 리턴되기 때문인 것도 추가적으로 알게 되었다.
이 구문의 이름은 컨텍스트 관리자로 리소스의 할당과 해제를 위해 만들어졌다고 한다. with 안에서 할일을 끝내면 자동적으로 리소스가 해제되니 가독성도 좋고, 오류 관리에도 좋다.
이 구문은 객체 내부에 매직 메서드 __enter__() 와 __exit__()이 정의되어 있다면 사용할 수 있다고 한다. 즉 달리 말하면 우리가 만들 객체에 __enter__()와 __exit__()이 있다면 컨텍스트 관리자를 사용할 수 있다는 말이 된다.
다만 __enter__ 에서 반환값이 있어야 하는데 그 이유를 <변수>에 들어갈 내용이 enter에서 반환되는 객체와 연결된다고 나는 이해했다. 변수명을 통해 접근하는 것이 __enter__에서 반환되는 객체 인 것.
두번째로 exit 에서는 예외처리를 원활히 하기 위해서 아래 예시와 같은 arguement를 포함하는 형태로 작성할 것을 권장한다고 한다.
class myContext():
def __init__(self):
self.temp = "커스텀 컨텍스트 시작"
def __enter__(self):
print(self.temp)
return self
def my_print(self):
print("어떤 일 하기")
def __exit__(self, exc_type, exc_val, exc_tb):
print("커스텀 컨텍스트 끝")
context = myContext()
with context as con:
con.my_print()
## 결과 값은 아래와 같이 나옵니다.
## 커스텀 컨텍스트 시작
## 어떤 일 하기
## 커스텀 컨텍스트 끝
결과는 __enter__()를 통해 객체를 접근하면서 init에서 설정된 self.temp를 출력했고, 내부 메서드를 사용 한 뒤 with 구문이 끝나면서 __exit__ 결과가 출력된 것을 확인할 수 있었다.