[Python] Asyncio_07

atesi·2022년 9월 27일
0

asyncio

목록 보기
7/7

Asynchronous Comprehensions

때로는 한 줄에 비동기 제너레이터를 만들고 싶을 때가 있다. Python 라이브러리는 Python 라이브러리에서 오랫동안 제공되었던 제너레이터 컴프리헨션과 비동기 유사체인 비동기 제너레이터 컴프리헨션의 형태로 이를 위해 사용할 수 있는 또 다른 shorthand를 제공한다.

it = (<async_expression> async for <variable> in <async_iterable> if <condition>)
async def _gen():
    async for <variable> in <async_iterable>:
        if <condition>:
            yield <async_expression>

it = _gen()

필요하지 않다면 if <condition>절을 생략할 수 있다. 하나의 비동기 제너레이터를 사용하여 한 줄의 코드로 다른 비동기 제너레이터를 만들 수 있다. 또한 <async_expression>, <async_iterable><condition>은 비동기 제너레이터의 본문에 포함되므로 비동기 코드를 포함할 수 있지만 statement 자체는 실제로 비동기 코드를 실행하지 않는다.

def sync_method(gen):
    # This is a synchronous method
    ...
    it = (
        await x.run()
        async for x in gen
        if not (await x.skip())
    )
    ...
    return it

일반적으로 허용되지 않는 동기 메소드에 await문을 포함하는 것처럼 보이지만 유효하다.

더 많은 혼란을 피하기 위해 동기코드를 사용하지 않는 비동기 컴프리헨션 the asynchronous list comprehension이 있다.

asynchronous list comprehension(코루틴 메서드의 본문과 같이 비동기식 코드가 허용되는 컨텍스트에서만 다시 나타날 수 있음)의 기본 형식은 다음과 같다.

l = [<async_expression> async for <variable> in <async_iterable> if <condition>]
async def _list():
    r = []
    async for <variable> in <async_iterable>:
        if <condition>:
            l.append(<async_expression>)
    return r

l = await _list()

제너레이터 버전과 미묘하게 다르다. 이 경우 묵시적으로 async def를 사용하여 코루틴 함수로 만든 다음 호출 하고 awaited한다. 이는 컴프리헨션이 배치되고 있는 context에서 발생하기 때문에 컴프리헨션은 await가 유효한 context에서만 사용할 수 있는것을 의미한다.

profile
Action!

0개의 댓글