Skip to content
Search

Python:With

lastmod 2023-09-14created 2020-03-228 edits

About the with statement in python.

How to use

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

Implementation

__enter__(self)
Called automatically when entering the with statement. Return the value that the as clause should receive.
__exit__(self, exception_type, exception_value, traceback)
Called automatically just before the with statement ends. The arguments describe the exceptions raised in the with statement.
If an exception is supplied and the with statement should suppress it (i.e., prevent it from being propagated), the method must return true. Otherwise, the exception continues to propagate after this method finishes.

Prototype information:

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

Sample example:

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 takes a class instance after with and, after as, a variable to store the result.

async with is available in Python 3.5 and later:

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

To make a class that works with async with, implement the __aenter__ and __aexit__ methods (meaning asynchronous enter and asynchronous exit). These methods must be defined with async def.

class 클래스이름:
    async def __aenter__(self):
        코드

    async def __aexit__(self, exc_type, exc_value, traceback):
        코드

Now let's make a class that returns the result of an addition after 1 second:

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

author Zer0 sitemap