Skip to content

Python:With

python의 with문에 대한 설명.

How to use

with open('copiedfile.txt', 'w', encoding='utf8') as f:
  f.write('test text')

Implementation

__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 withwith 다음에 클래스의 인스턴스를 지정하고 as 뒤에 결과를 저장할 변수를 지정합니다.

async with은 파이썬 3.5 이상부터 사용 가능:

async with 클래스() as 변수:
    코드

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()

See also

Favorite site