Python:With
python의 with
문에 대한 설명.
How to use
Implementation
- 3. 데이터 모델 — Python 3.11.5 문서 # object.exit
- What are the python builtin exit argument types? - Stack Overflow
-
__enter__(self)
- with 문에 진입하는 시점에 자동으로 호출된다. 반환 값은
as
문으로 받을 값을 반환하면 된다.
-
__exit__(self, exception_type, exception_value, traceback)
- with 문이 끝나기 직전에 자동으로 호출된다. 인자들은
with
문에서 발생한 예외들에 대한 내용들이다. - 만약 예외가 제공되고,
with
문에서 (즉, 전파를 것을 막으려면) 참(true)을 돌려줘야 합니다. 그렇지 않으면 예외는 이 메서드가 종료한 후에 계속 전파됩니다.
프로토타입 정보:
from typing import Any, Literal, Optional, Type
from types import TracebackType
...
def __enter__(self) -> Any:
self.begin = datetime.now()
self.error = None
return self
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> Optional[Literal[True]]:
self.error = exc_val
self.end = datetime.now()
# If an exception is supplied, and the method wishes to suppress the exception
# (i.e., prevent it from being propagated), it should return a true value
return None
샘플 예제:
class Hello:
def __enter__(self):
# 사용할 자원을 가져오거나 만든다(핸들러 등)
print('enter...')
return self # 반환값이 있어야 VARIABLE를 블록내에서 사용할 수 있다
def sayHello(self, name):
# 자원을 사용한다. ex) 인사한다
print('hello ' + name)
def __exit__(self, exc_type, exc_val, exc_tb):
# 마지막 처리를 한다(자원반납 등)
print('exit...')
async with
async with
은 with
다음에 클래스의 인스턴스를 지정하고 as
뒤에 결과를 저장할 변수를 지정합니다.
async with
은 파이썬 3.5 이상부터 사용 가능:
async with
으로 동작하는 클래스를 만들려면 __aenter__
와 __aexit__
메서드를 구현해야 합니다 (asynchronous enter, asynchronous exit라는 뜻). 그리고 메서드를 만들 때는 반드시 async def
를 사용합니다.
class 클래스이름:
async def __aenter__(self):
코드
async def __aexit__(self, exc_type, exc_value, traceback):
코드
그럼 1초 뒤에 덧셈 결과를 반환하는 클래스를 만들어보겠습니다:
asyncio_async_with.py
import asyncio
class AsyncAdd:
def __init__(self, a, b):
self.a = a
self.b = b
async def __aenter__(self):
await asyncio.sleep(1.0)
return self.a + self.b # __aenter__에서 값을 반환하면 as에 지정한 변수에 들어감
async def __aexit__(self, exc_type, exc_value, traceback):
pass
async def main():
async with AsyncAdd(1, 2) as result: # async with에 클래스의 인스턴스 지정
print(result) # 3
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
loop.close()