← Назад к вопросам

Что такое future?

2.2 Middle🔥 161 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Future в Python — асинхронное выполнение

Future — это объект, который представляет результат асинхронной операции, которая произойдёт в будущем. Это основной строительный блок асинхронного программирования в Python.

Концепция Future

Текущее время        Будущее время
     ↓                    ↓
┌────────────────────────────┐
│  Future создан             │
│  (результата ещё нет)      │
│         ↓                  │
│  Операция выполняется      │
│         ↓                  │
│  Future получает результат │
│  (можно получить значение) │
└────────────────────────────┘

Future в модуле concurrent.futures

ThreadPoolExecutor — многопоточность

from concurrent.futures import ThreadPoolExecutor
import time

def slow_function(n):
    time.sleep(2)
    return n * 2

# Создание пула потоков
with ThreadPoolExecutor(max_workers=3) as executor:
    # Запустить функцию асинхронно
    future = executor.submit(slow_function, 5)
    
    print("Код выполняется, пока функция работает в другом потоке")
    
    # Получить результат (блокирует если результата ещё нет)
    result = future.result()  # Ждёт 2 секунды
    print(f"Результат: {result}")  # 10

ProcessPoolExecutor — многопроцессность

from concurrent.futures import ProcessPoolExecutor

def cpu_intensive(n):
    # Долгая вычислительная операция
    total = 0
    for i in range(n * 1000000):
        total += i
    return total

with ProcessPoolExecutor(max_workers=4) as executor:
    futures = [executor.submit(cpu_intensive, i) for i in range(1, 5)]
    
    # Получить результаты по мере готовности
    for future in futures:
        result = future.result()
        print(f"Результат: {result}")

Методы Future

result() — получить результат

future = executor.submit(some_function)
value = future.result(timeout=5)  # Ждёт максимум 5 сек

done() — проверить готовность

future = executor.submit(slow_function)

if future.done():
    print(f"Готово: {future.result()}")
else:
    print("Ещё выполняется")

cancel() — отменить выполнение

future = executor.submit(slow_function)

if future.cancel():
    print("Успешно отменено")
else:
    print("Уже выполняется, отменить нельзя")

add_done_callback() — обработчик завершения

def on_complete(future):
    result = future.result()
    print(f"Функция завершена! Результат: {result}")

future = executor.submit(slow_function, 5)
future.add_done_callback(on_complete)
# Код продолжает выполняться

as_completed() — обработка результатов по мере готовности

from concurrent.futures import as_completed

urls = ['url1', 'url2', 'url3', 'url4']

with ThreadPoolExecutor(max_workers=4) as executor:
    # Запустить задачи
    futures = {executor.submit(fetch_url, url): url for url in urls}
    
    # Обработать результаты по мере готовности (не по порядку)
    for future in as_completed(futures):
        url = futures[future]
        try:
            data = future.result()
            print(f"{url}: успешно получено")
        except Exception as e:
            print(f"{url}: ошибка {e}")

Future в asyncio

asyncio использует другой подход — async/await (более эффективный для IO):

import asyncio

async def slow_async_function(n):
    await asyncio.sleep(2)
    return n * 2

async def main():
    # Создать Future (в asyncio это Task)
    task = asyncio.create_task(slow_async_function(5))
    
    print("Код продолжает выполняться")
    
    # Ждать результат
    result = await task
    print(f"Результат: {result}")  # 10

asyncio.run(main())

Несколько задач параллельно

import asyncio

async def fetch_data(url, delay):
    await asyncio.sleep(delay)
    return f"Данные с {url}"

async def main():
    # Создать несколько задач
    tasks = [
        asyncio.create_task(fetch_data('url1', 1)),
        asyncio.create_task(fetch_data('url2', 2)),
        asyncio.create_task(fetch_data('url3', 1.5)),
    ]
    
    # Ждать все задачи
    results = await asyncio.gather(*tasks)
    print(results)
    # ['Данные с url1', 'Данные с url2', 'Данные с url3']

asyncio.run(main())

Разница: Future vs Task vs async/await

concurrent.futures.Future

# Для многопоточности/многопроцессности
with ThreadPoolExecutor() as e:
    future = e.submit(func)  # Блокирующая операция
    result = future.result()  # Ждёт

asyncio.Task

# Для асинхронных операций (IO)
task = asyncio.create_task(async_func())  # Неблокирующая операция
result = await task  # Ждёт асинхронно

async/await — рекомендуется

# Более читаемо и эффективно
async def main():
    result = await async_func()

Практический пример: загрузка нескольких URL

Плохо (синхронно, медленно)

import requests

urls = ['http://api.example.com/1', 'http://api.example.com/2']

# Займёт ~4 секунды (2 сек + 2 сек)
for url in urls:
    response = requests.get(url)  # Блокирует
    print(response.json())

Хорошо (asyncio, быстро)

import asyncio
import aiohttp

async def fetch(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.json()

async def main():
    urls = ['http://api.example.com/1', 'http://api.example.com/2']
    
    # Займёт ~2 секунды (параллельно)
    tasks = [asyncio.create_task(fetch(url)) for url in urls]
    results = await asyncio.gather(*tasks)
    
    for result in results:
        print(result)

asyncio.run(main())

Обработка исключений в Future

from concurrent.futures import ThreadPoolExecutor

def risky_function():
    raise ValueError("Что-то пошло не так")

with ThreadPoolExecutor() as executor:
    future = executor.submit(risky_function)
    
    try:
        result = future.result()
    except ValueError as e:
        print(f"Перехвачена ошибка: {e}")

Когда использовать Future

concurrent.futures.Future

  • CPU-intensive задачи → ProcessPoolExecutor
  • Blocking I/O (requests, database) → ThreadPoolExecutor
  • Интеграция с legacy кодом

asyncio (рекомендуется)

  • Async I/O (aiohttp, asyncpg)
  • Много одновременных соединений
  • Микросервисы, REST API
  • Более эффективен по памяти и CPU

Простое объяснение

Future — это как заказ в кафе:

  1. Вы заказываете кофе (создаёте Future)
  2. Кассир принимает заказ и говорит номер
  3. Вы можете спросить готов ли кофе (future.done())
  4. Когда кофе готов, вы его получаете (future.result())

Без Future вам пришлось бы ждать у кассы, пока кофе готовится (блокирующее выполнение). С Future вы можете делать другие дела (future.result()), пока кофе готовится в фоне.