Как сделать паузу в Python: time.sleep() и asyncio.sleep()
Оглавление статьи

Короткий ответ
Чтобы сделать паузу в обычном Python-коде, вызовите time.sleep(seconds). Функция приостанавливает текущий поток минимум на указанное число секунд. В асинхронном коде используйте await asyncio.sleep(seconds): она приостанавливает только текущую задачу и отдаёт управление циклу событий.
import time
print("Старт")
time.sleep(2)
print("Прошло не меньше двух секунд")Главное правило выбора: time.sleep() - для синхронного сценария, asyncio.sleep() - внутри корутины. Вызов time.sleep() внутри async def блокирует поток цикла событий и мешает другим задачам выполняться.
Как работает time.sleep()
time.sleep(seconds) входит в стандартный модуль time и не требует установки пакетов. Аргумент задаётся в секундах и может быть целым или дробным числом. Например, 0.5 означает половину секунды, а 0.001 - одну миллисекунду как запрошенный интервал.
import time
for step in range(3):
print(f"Шаг {step + 1}")
time.sleep(0.5)Документация Python 3.14 уточняет: фактическая остановка может оказаться длиннее запрошенной из-за планирования других процессов и потоков операционной системой. Поэтому sleep() подходит для задержки, но не для точного таймера реального времени.
time.sleep() приостанавливает вызывающий поток, а не обязательно весь процесс. Другие потоки могут продолжать работу. Но если это главный поток GUI или поток с циклом asyncio, интерфейс или все корутины этого цикла перестанут отвечать до окончания паузы.time.sleep() и asyncio.sleep(): в чём разница
| Критерий | time.sleep() | asyncio.sleep() |
|---|---|---|
| Где использовать | Обычная функция, синхронный скрипт | Корутина async def |
| Как вызвать | time.sleep(1) | await asyncio.sleep(1) |
| Что приостанавливается | Текущий поток | Текущая задача |
| Могут ли выполняться другие корутины того же цикла | Нет, если вызов сделан в потоке event loop | Да |
| Возвращаемое значение | None | Переданный result или None |
| Нужен ли event loop | Нет | Да |
asyncio.sleep() всегда приостанавливает текущую задачу и позволяет циклу событий запустить готовую к работе корутину. Даже await asyncio.sleep(0) отдаёт управление планировщику по оптимизированному пути. Это не «сон всего приложения», а момент кооперативного переключения.
Пример asyncio.sleep() с двумя задачами
import asyncio
async def worker(name: str, delay: float) -> None:
print(f"{name}: старт")
await asyncio.sleep(delay)
print(f"{name}: готово")
async def main() -> None:
await asyncio.gather(
worker("A", 1.0),
worker("B", 0.5),
)
asyncio.run(main())Обе корутины стартуют, затем задача B становится готовой раньше задачи A. Если заменить await asyncio.sleep(delay) на time.sleep(delay), каждый вызов заблокирует поток event loop, и полезная конкурентность исчезнет.
Начиная с Python 3.13, asyncio.sleep(float("nan")) вызывает ValueError. Значение задержки, полученное из настроек или внешних данных, стоит проверять: оно должно быть конечным неотрицательным числом с понятной верхней границей.
Как сделать паузу на миллисекунды
Оба варианта принимают секунды как float. Переводите миллисекунды в секунды делением на 1000:
import time
milliseconds = 250
time.sleep(milliseconds / 1000)Это запрос на паузу около 250 миллисекунд, а не гарантия пробуждения с точностью до миллисекунды. Разрешение таймера зависит от операционной системы, а выполнение продолжится только когда планировщик снова даст потоку процессорное время. Для измерения прошедшего интервала используйте time.perf_counter() или time.monotonic(), а не календарные часы.
Периодический запуск без накопления дрейфа
Цикл вида «работа, затем sleep(1)» постепенно отстаёт: длительность самой работы добавляется к каждому периоду. Для стабильного интервала рассчитывайте следующий дедлайн по монотонным часам.
import time
period = 1.0
next_run = time.monotonic()
for _ in range(5):
print("Выполняем задачу")
next_run += period
remaining = next_run - time.monotonic()
time.sleep(max(0.0, remaining))time.monotonic() не движется назад при ручной смене системного времени. Если работа длится дольше периода, remaining станет отрицательным и очередная пауза будет нулевой. Для производственного планировщика нужно отдельно решить, пропускать ли просроченные запуски, объединять их или выполнять подряд.
Отменяемое ожидание в потоке
Спящий поток нельзя штатно разбудить через сам time.sleep(). Если фоновая задача должна быстро завершаться по сигналу, удобнее ждать threading.Event. Метод wait(timeout) возвращает True, когда событие установлено, и False, когда истёк таймаут.
import threading
stop_event = threading.Event()
def worker() -> None:
while not stop_event.wait(timeout=5.0):
print("Пять секунд прошли, продолжаем")
# Из другого потока:
stop_event.set()Так фоновый цикл завершится сразу после set(), а не будет ждать остаток фиксированной паузы. В асинхронном коде отмена устроена иначе: задача, ожидающая asyncio.sleep(), может быть отменена и получит asyncio.CancelledError в ближайшей точке отмены. Очистку ресурсов размещайте в finally.
Задержка между повторными запросами
Фиксированная пауза между сетевыми повторами может создать синхронный всплеск нагрузки. Обычно используют экспоненциальный backoff с ограничением и случайным разбросом. Но сначала нужно выполнить правила конкретного : учитывать Retry-After, лимиты, идемпотентность операции и максимальное число попыток.
import random
import time
def backoff(attempt: int, base: float = 0.5, cap: float = 30.0) -> None:
upper = min(cap, base * 2 ** attempt)
time.sleep(random.uniform(0.0, upper))Этот фрагмент только рассчитывает паузу. Он не решает, можно ли повторять запрос, и не заменяет обработку HTTP-ответов. Не повторяйте автоматически оплату, создание заказа или другую неидемпотентную операцию без ключа идемпотентности и правил сервиса.
Когда sleep() использовать не стоит
Ожидание готовности файла или сервиса. Проверяйте состояние с таймаутом либо используйте событие, очередь или callback.
Таймаут сетевой операции. Передавайте таймаут клиентской библиотеке; иначе запрос может зависнуть внутри вызова раньше вашего
sleep().Пауза в интерфейсе. Используйте таймер GUI-фреймворка, чтобы не блокировать главный цикл событий.
Синхронизация потоков. Применяйте
Event,Condition,Lockили очередь, а не угадывайте время выполнения.Планирование на часы и дни. Нужен планировщик с хранением состояния, обработкой перезапуска и часовых поясов.
CPU-bound задача в asyncio.
asyncio.sleep()не ускоряет вычисления; выносите блокирующую работу в подходящий поток или процесс.
Частые ошибки
Писать
sleep(1)безimport timeили явного импорта метода.Передавать миллисекунды как секунды и случайно ждать в тысячу раз дольше.
Забывать
awaitпередasyncio.sleep(): создаётся объект корутины, но пауза не выполняется.Вызывать
time.sleep()внутриasync defи блокировать event loop.Считать паузу точным будильником и игнорировать задержку планировщика.
Использовать
time.time()для интервалов, хотя системные часы могут быть переведены.Останавливать интерфейс
sleep()в главном потоке.Добавлять задержку вместо явной синхронизации или настоящего таймаута операции.
Как выбрать способ ожидания
| Задача | Инструмент |
|---|---|
| Простая пауза в синхронном скрипте | time.sleep() |
| Неблокирующая пауза в корутине | await asyncio.sleep() |
| Отменяемое ожидание фонового потока | threading.Event.wait() |
| Измерение длительности | time.perf_counter() |
| Расчёт дедлайна и периода | time.monotonic() |
| Таймаут асинхронной операции | asyncio.timeout() или таймаут библиотеки |
| Отложенное действие в GUI | Таймер конкретного GUI-фреймворка |
Чек-лист перед добавлением паузы
Код синхронный или асинхронный?
Можно ли ждать событие вместо фиксированного времени?
Допустимо ли блокировать текущий поток?
Нужна ли возможность немедленной отмены?
Значение переведено в секунды и проверено на границы?
Используется монотонный таймер для интервалов?
У сетевой операции есть собственный таймаут?
Повтор запроса разрешён и не создаст дубль операции?
Вывод
time.sleep() - простой способ приостановить текущий поток в синхронном скрипте. asyncio.sleep() решает другую задачу: временно приостанавливает корутину и позволяет event loop выполнять другие задачи. Для отменяемого ожидания потока выбирайте Event.wait(), для интервалов - монотонные часы, а для сетевых и GUI-сценариев - таймауты и таймеры соответствующей библиотеки. Больше базовых конструкций собрано в практическом путеводителе по Python.
Официальные источники
Часто задаваемые вопросы
Как сделать паузу в Python?
В синхронном коде импортируйте модуль time и вызовите time.sleep(seconds). Функция приостановит текущий поток минимум на указанное число секунд.
Как сделать задержку на миллисекунды в Python?
Разделите миллисекунды на 1000: time.sleep(milliseconds / 1000). Это запрошенная минимальная пауза, а не гарантия точного пробуждения из-за работы системного планировщика.
Чем asyncio.sleep() отличается от time.sleep()?
time.sleep() блокирует текущий поток. await asyncio.sleep() приостанавливает только текущую асинхронную задачу и позволяет циклу событий выполнять другие готовые задачи.
Можно ли использовать time.sleep() внутри async def?
Технически вызов возможен, но он заблокирует поток event loop и остановит другие корутины этого цикла. В асинхронной функции обычно нужен await asyncio.sleep().
Почему asyncio.sleep() не работает без await?
asyncio.sleep() возвращает объект корутины. Без await, создания задачи или другого запуска корутина не выполняется, поэтому фактической паузы не происходит.
time.sleep() останавливает весь Python-процесс?
Она приостанавливает вызывающий поток. Другие потоки процесса могут продолжать работу, но пауза в главном потоке GUI или event loop блокирует обслуживаемые им задачи.
Как прервать sleep в потоке?
У time.sleep() нет штатного сигнала пробуждения. Для отменяемого ожидания используйте threading.Event.wait(timeout) и вызовите set() из другого потока.
Подходит ли sleep для точного таймера?
Нет. Пауза может длиться дольше запрошенной. Для измерения используйте time.perf_counter(), для дедлайнов time.monotonic(), а для точного планирования специализированный механизм.
Комментарии 0
Обсудите материал, задайте вопрос или дополните его своим опытом.
Комментарии доступны зарегистрированным пользователям. Почту нужно подтвердить один раз.
Начните обсуждение: задайте вопрос автору или поделитесь практическим опытом.