# 퓨처

소스 코드: Lib/asyncio/futures.py, Lib/asyncio/base_futures.py

Future 객체는 저수준 콜백 기반 코드와 고수준 async/await 코드 간에 다리를 놓는 데 사용됩니다.

## 퓨처 함수

`asyncio.``isfuture`(obj)

  obj가 다음 중 하나면 `True`를 반환합니다:

  - `asyncio.Future`의 인스턴스,

  - `asyncio.Task`의 인스턴스,

  - `_asyncio_future_blocking` 어트리뷰트를 가진 퓨처류 객체.

  버전 3.5에 추가.

`asyncio.``ensure_future`(obj, *, loop=None)

  다음을 반환합니다:

  - obj가 `Future`, `Task` 또는 퓨처류 객체면, obj 인자를 있는 그대로 (`isfuture()`로 검사합니다.)

  - obj가 코루틴이면, obj를 감싸는 `Task` 객체 (`iscoroutine()`로 검사합니다); 이 경우 코루틴은 `ensure_future()`로 예약됩니다.

  - obj가 어웨이터블이면, obj를 기다릴 `Task` 객체 (`inspect.isawaitable()`로 검사합니다.)

  obj가 이 중 어느 것도 아니면, `TypeError`가 발생합니다.

  중요

  새 태스크를 만드는 데 선호되는 `create_task()` 함수도 참조하십시오.

  버전 3.5.1에서 변경: 함수는 모든 어웨이터블 객체를 받아들입니다.

`asyncio.``wrap_future`(future, *, loop=None)

  `concurrent.futures.Future` 객체를 `asyncio.Future` 객체로 감쌉니다.

## Future 객체

class `asyncio.``Future`(*, loop=None)

  Future는 비동기 연산의 최종 결과를 나타냅니다. 스레드 안전하지 않습니다.

  Future는 어웨이터블 객체입니다. 코루틴은 결과나 예외가 설정되거나 취소될 때까지 Future 객체를 기다릴 수 있습니다.

  일반적으로 퓨처는 저수준 콜백 기반 코드(예를 들어, asyncio 트랜스포트를 사용하여 구현된 프로토콜에서)가 고수준 async/await 코드와 상호 운용되도록 하는 데 사용됩니다.

  간단한 규칙은 사용자가 만나는 API에서 Future 객체를 절대 노출하지 않는 것이며, Future 객체를 만드는 권장 방법은 `loop.create_future()`를 호출하는 것입니다. 이런 식으로 대체 이벤트 루프 구현이 자신의 최적화된 Future 객체 구현을 주입할 수 있습니다.

  버전 3.7에서 변경: `contextvars` 모듈에 대한 지원이 추가되었습니다.

  `result`()

    Future의 결과를 반환합니다.

    Future가 완료(done)했고 `set_result()` 메서드로 결과가 설정되었으면, 결괏값이 반환됩니다.

    Future가 완료(done)했고 `set_exception()` 메서드로 예외가 설정되었으면, 이 메서드는 예외를 발생시킵니다.

    Future가 취소(cancelled)되었으면, 이 메서드는 `CancelledError` 예외를 발생시킵니다.

    Future의 결과를 아직 사용할 수 없으면, 이 메서드는 `InvalidStateError` 예외를 발생시킵니다.

  `set_result`(result)

    Future를 완료(done)로 표시하고, 그 결과를 설정합니다.

    Future가 이미 완료(done)했으면, `InvalidStateError` 에러를 발생시킵니다.

  `set_exception`(exception)

    Future를 완료(done)로 표시하고, 예외를 설정합니다.

    Future가 이미 완료(done)했으면, `InvalidStateError` 에러를 발생시킵니다.

  `done`()

    Future가 완료(done)했으면 `True`를 반환합니다.

    Future는 취소(cancelled)되었거나 `set_result()` 나 `set_exception()` 호출로 결과나 예외가 설정되면 완료(done)됩니다.

  `cancelled`()

    Future가 최소(cancelled)되었으면, `True`를 반환합니다.

    이 메서드는 대개 결과나 예외를 설정하기 전에 Future가 취소(cancelled)되었는지 확인하는 데 사용됩니다:

        if not fut.cancelled():
            fut.set_result(42)

  `add_done_callback`(callback, *, context=None)

    Future가 완료(done)될 때 실행할 콜백을 추가합니다.

    callback는 유일한 인자인 Future 객체로 호출됩니다.

    이 메서드가 호출될 때 Future가 이미 완료(done)되었으면, 콜백이 `loop.call_soon()`으로 예약됩니다.

    선택적 키워드 전용 context 인자는 callback이 실행될 사용자 정의 `contextvars.Context`를 지정할 수 있도록 합니다. context가 제공되지 않으면 현재 컨텍스트가 사용됩니다.

    `functools.partial()`을 사용하여 매개 변수를 callback에 전달할 수 있습니다, 예를 들어:

        # Call 'print("Future:", fut)' when "fut" is done.
        fut.add_done_callback(
            functools.partial(print, "Future:"))

    버전 3.7에서 변경: context 키워드 전용 매개 변수가 추가되었습니다. 자세한 내용은 PEP 567을 참조하십시오.

  `remove_done_callback`(callback)

    콜백 목록에서 callback을 제거합니다.

    제거된 콜백 수를 반환합니다. 콜백이 두 번 이상 추가되지 않는 한 일반적으로 1입니다.

  `cancel`()

    Future를 취소하고 콜백을 예약합니다.

    Future가 이미 완료(done)했거나 취소(cancelled)되었으면, `False`를 반환합니다. 그렇지 않으면 Future의 상태를 취소(cancelled)로 변경하고, 콜백을 예약한 다음 `True`를 반환합니다.

  `exception`()

    이 Future에 설정된 예외를 반환합니다.

    Future가 완료(done)했을 때만 예외(또는 예외가 설정되지 않았으면 `None`)가 반환됩니다.

    Future가 취소(cancelled)되었으면, 이 메서드는 `CancelledError` 예외를 발생시킵니다.

    Future가 아직 완료(done)하지 않았으면, 이 메서드는 `InvalidStateError` 예외를 발생시킵니다.

  `get_loop`()

    Future 객체가 연결된 이벤트 루프를 반환합니다.

    버전 3.7에 추가.

이 예제는 Future 객체를 만들고, Future에 결과를 설정하는 비동기 Task를 만들고 예약하며, Future가 결과를 얻을 때까지 기다립니다:

    async def set_after(fut, delay, value):
        # Sleep for *delay* seconds.
        await asyncio.sleep(delay)

        # Set *value* as a result of *fut* Future.
        fut.set_result(value)

    async def main():
        # Get the current event loop.
        loop = asyncio.get_running_loop()

        # Create a new Future object.
        fut = loop.create_future()

        # Run "set_after()" coroutine in a parallel Task.
        # We are using the low-level "loop.create_task()" API here because
        # we already have a reference to the event loop at hand.
        # Otherwise we could have just used "asyncio.create_task()".
        loop.create_task(
            set_after(fut, 1, '... world'))

        print('hello ...')

        # Wait until *fut* has a result (1 second) and print it.
        print(await fut)

    asyncio.run(main())

중요

Future 객체는 `concurrent.futures.Future`를 흉내 내도록 설계되었습니다. 주요 차이점은 다음과 같습니다:

- asyncio 퓨처와는 달리, `concurrent.futures.Future` 인스턴스는 await 할 수 없습니다.

- `asyncio.Future.result()` 와 `asyncio.Future.exception()`은 timeout 인자를 받아들이지 않습니다.

- `asyncio.Future.result()` 와 `asyncio.Future.exception()`는 Future가 완료(done)하지 않았을 때 `InvalidStateError` 예외를 발생시킵니다.

- `asyncio.Future.add_done_callback()`으로 등록된 콜백은 즉시 호출되지 않습니다. 대신 `loop.call_soon()`로 예약됩니다.

- asyncio Future는 `concurrent.futures.wait()` 와 `concurrent.futures.as_completed()` 함수와 호환되지 않습니다.