# 퓨처

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

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

## 퓨처 함수

asyncio.isfuture(obj)

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

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

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

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

  Added in version 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()` 함수도 참조하십시오.

  Save a reference to the result of this function, to avoid a task disappearing mid-execution.

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

  버전 3.10부터 폐지됨: Deprecation warning is emitted if obj is not a Future-like object and loop is not specified and there is no running event loop.

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

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

  버전 3.10부터 폐지됨: Deprecation warning is emitted if future is not a Future-like object and loop is not specified and there is no running event loop.

## Future 객체

class asyncio.Future(*, loop=None)

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

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

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

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

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

  버전 3.10부터 폐지됨: Deprecation warning is emitted if loop is not specified and there is no running event loop.

  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에 전달할 수 있습니다, 예를 들어:

        # "fut"가 완료되면 'print("Future:", fut)'를 호출합니다.
        fut.add_done_callback(
            functools.partial(print, "Future:"))

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

  remove_done_callback(callback)

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

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

  cancel(msg=None)

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

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

    버전 3.9에서 변경: msg 매개 변수를 추가했습니다.

  exception()

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

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

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

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

  get_loop()

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

    Added in version 3.7.

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

    async def set_after(fut, delay, value):
        # *delay* 초 동안 잠잡니다.
        await asyncio.sleep(delay)

        # *fut* 퓨처의 결과로 *value* 를 설정합니다.
        fut.set_result(value)

    async def main():
        # 현재 이벤트 루프를 얻습니다.
        loop = asyncio.get_running_loop()

        # 새로운 Future 객체를 만듭니다.
        fut = loop.create_future()

        # 병렬 태스크로 "set_after()" 코루틴을 실행합니다.
        # 이벤트 루프에 대한 참조를 이미 가지고 있으므로, 여기서는 저수준 "loop.create_task()"
        # API를 사용하고 있습니다.
        # 그렇지 않다면 그저 "asyncio.create_task()" 를 사용할 수 있었습니다.
        loop.create_task(
            set_after(fut, 1, '... world'))

        print('hello ...')

        # *fut* 에 결과가 올 때까지 기다렸다가 (1초) 그것을 인쇄합니다.
        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()` 함수와 호환되지 않습니다.

- `asyncio.Future.cancel()`은 선택적 `msg` 인자를 받아들이지만, `concurrent.futures.Future.cancel()`은 받아들이지 않습니다.