Как сделать таймер в python

Добавил пользователь Дмитрий К.
Обновлено: 05.10.2024

Класс Timer() модуля threading создает таймер, который будет запускать функцию function с аргументами args и ключевыми аргументами kwargs по прошествии интервала interval секунд.

Если args равен None (по умолчанию), то будет использоваться пустой список. Если kwargs равен None (по умолчанию), то будет использоваться пустой словарь.

Этот класс представляет действие, которое следует запускать только по прошествии определенного времени — таймер. Таймер является подклассом threading.Thread() и, как таковой, также служит примером создания пользовательских потоков.

Таймеры запускаются, как и потоки, путем вызова их метода Timer.start() , унаследованного от класса threading.Thread() .

Таймер можно остановить до того, как его действие начнется, вызвав метод Timer.cancel() . Интервал, который таймер будет ожидать перед выполнением своего действия, может не совпадать с интервалом, указанным пользователем.

Методы объекта Timer .

Объект Timer дополнительно определяет один метод. Остальные методы он наследует от класса threading.Thread() .

Timer.cancel() :

Метод Timer.cancel() останавливает таймер и отменяет выполнение действия таймера. Метод будет работать только в том случае, если таймер все еще находится в стадии ожидания.

Сработавший таймер остановить нельзя.

Примеры создания и запуска потоков-таймеров.

Таймер начинает свою работу после задержки и может быть отменен в любой момент в течение этого времени задержки.

Второй таймер в этом примере никогда не запускается, а первый таймер запускается после того, как остальная часть основной программы завершена.

Python. Урок 23. Потоки и процессы в Python. Часть 2. Синхронизация потоков

Синхронизация потоков

Начнем наш обзор с наиболее простого и, в то же время, общего по своим свойствам Lock -объекта.

Lock-объект

Lock -объект может находится в двух состояниях: захваченное (заблокированное) и не захваченное (не заблокированное, свободное). После создания он находится в свободном состоянии . Для работы с Lock -объектом используются методы acquire() и release() . Если Lock свободен, то вызов метода acquire() переводит его в заблокированное состояние. Повторный вызов acquire() приведет к блокировке инициировавшего это действие потока до тех пор, пока Lock не будет разблокирован каким-то другим потоком с помощью метода release() . Вывоз метода release() на свободном Lock -объекте приведет к выбросу исключения RuntimeError .

Метод acquire() имеет следующую сигнатуру:

acquire(blocking=True, timeout=-1)

  • blocking
  • Если параметр равен True , то при вызове на захваченном Lock -объекте выполнение потока остановится, после того как захват будет произведет, метод вернет True . Если параметр равен False , то при вызове на захваченном Lock -объекте поток не будет заблокирован и метод вернет False , если захват будет произведет, то вернет True .
  • Задает время, в течении которого поток будет находиться в заблокированном состоянии при попытке захватить уже занятый Lock -объект. Если в течении заданного времени поток не освободится, то метод вернет значение False .

При успешном захвате Lock -объекта, метод acquire() возвращает значение True .

У Lock -объекта также есть метод locked() , который возвращает True если объект захвачен, False в противном случае.

Мы уже успели познакомиться с Lock -объектом, когда изучали вопрос принудительного завершения работы потока в “Уроке 22. Процессы и потоки в Python . Часть 1 ”.

Освободить Lock -объект может любой поток (на обязательно тот, который вызвал acquire() ).

Хорошей практикой при работе с Lock -объектами является помещение кода работы с разделяемым ресурсом в блоке try , а освобождать блокировку следует в finally :

RLock-объект

В отличии от рассмотренного выше Lock -объекта RLock может освободить только тот поток, который его захватил . Повторный захват потоком уже захваченного RLock -объекта не блокирует его. RLock -объекты поддерживают возможность вложенного захвата, при этом освобождение происходит только после того, как был выполнен release() для внешнего acquire() . Сигнатуры и назначение методов release() и acquire() RLock -объектов совпадают с приведенными для Lock , но в отличии от него у RLock нет метода locked() . RLock -объекты поддерживают протокол менеджера контекста.

Условные переменные (threading.Condition)

Порядок работы с условными переменными выглядит так:

На стороне Consumer’а : проверить доступен ли ресурс, если нет, то перейти в режим ожидания с помощью метода wait() , и ожидать оповещение от Producer’а о том, что ресурс готов и с ним можно работать. Метод wait() может быть вызван с таймаутом, по истечении которого поток выйдет из состояния блокировки и продолжит работу.

На стороне Producer’а : произвести работы по подготовке ресурса, после того, как ресурс готов оповестить об этом ожидающие потоки с помощью методов notify() или notify_all() . Разница между ними в том, что notify() разблокирует только один поток (если он вызван без параметров), а notify_all() все потоки, которые находятся в режиме ожидания.

Ниже представлен пример работы с условной переменной.

При создании объекта Condition вы можете передать в конструктор объект Lock или RLock , с которым хотите работать. Перечислим методы объекта Condition с кратким описанием:

  • acquire(*args)
  • Захват объекта-блокировки.
  • Освобождение объекта-блокировки.
  • Блокировка выполнения потока до оповещения о снятии блокировки. Через параметр timeout можно задать время ожидания оповещения о снятии блокировки. Если вызвать wait() на Условной переменной, у которой предварительно не был вызван acquire() , то будет выброшено исключение RuntimeError .
  • Метод позволяет сократить количество кода, которое нужно написать для контроля готовности ресурса и ожидания оповещения. Он заменяет собой следующую конструкцию:
  • notify(n=1)
  • Снимает блокировку с остановленного методом wait() потока. Если необходимо разблокировать несколько потоков, то для этого следует передать их количество через аргумент n .
  • Снимает блокировку со всех остановленных методом wait() потоков.

Семафоры (threading.Semaphore)

Семафоры поддерживают протокол менеджера контекста.

Для работы с семафорами в Python есть класс Semaphore , при создании его объекта можно указать начальное значение счетчика через параметр value . Semaphore предоставляет два метода:

  • acquire(blocking=True, timeout=None)
  • Если значение внутреннего счетчика больше нуля, то счетчик уменьшается на единицу и метод возвращает True . Если значение счетчика равно нулю, то вызвавший данный метод поток блокируется, до тех пор, пока не будет кем-то вызван метод release() . Дополнительно при вызове метода можно указать параметры blocking и timeout , их назначение совпадает с acquire() для Lock .
  • Увеличивает значение внутреннего счетчика на единицу.

Существует ещё один класс, реализующий алгоритм семафора BoundedSemaphore , в отличии от Semaphore , он проверяет, чтобы значение внутреннего счетчика было не больше того, что передано при создании объекта через аргумент value , если это происходит, то выбрасывается исключение ValueError .

С помощью семафоров удобно управлять доступом к ресурсу, который имеет ограничение на количество одновременных обращений к нему (например, количество подключений к базе данных и т.п.)

В качестве примера приведем программу, моделирующую продажу билетов: обслуживание одного клиента занимает одну секунду, касс всего три, клиентов пять.

Как вы можете видеть, вначале обслуживание получили клиенты с номерами 0, 1, 2 и только после того, как кассы по продаже билетов освободились, были обслужены клиенты 3 и 4.

События (threading.Event)

Методы класса Event :

  • is_set()
  • Возвращает True если флаг находится в взведенном состоянии.
  • Переводит флаг в взведенное состояние.
  • Переводит флаг в сброшенное состояние.
  • Блокирует вызвавший данный метод поток если флаг соответствующего Event- объекта находится в сброшенном состоянии. Время нахождения в состоянии блокировки можно задать через параметр timeout .

Пример работы с Event- объектом:

Содержимое консоли после вызова приведенной Python -программы:

Порядок пробуждения потоков при использовании объекта Event никак не регламентируется, поэтому вы можете видеть, что поток с номером 0 закончил работу последним, хотя был запущен первым.

Таймеры (threading.Timer)

Конструктор класса Timer :

Timer(interval, function, args=None, kwargs=None)

  • interval
  • Количество секунд, по истечении которых будет вызвана функция function .
  • Функция, вызов которой нужно осуществить по таймеру.
  • Аргументы функции function .

Методы класса Timer :

  • cancel()
  • Останавливает выполнение таймера

Пример работы с таймером:

Барьеры (threading.Barrier)

Последний инструмент для синхронизации работы потоков, который мы рассмотрим является Barrier . Он позволяет реализовать алгоритм, когда необходимо дождаться завершения работы группы потоков, прежде чем продолжить выполнение задачи.

Barrier(parties, action=None, timeout=None)

  • parties
  • Количество потоков, которые будут работать в рамках барьера.
  • Определяет функцию, которая будет вызвана, когда потоки будут освобождены (достигнут барьера).
  • Таймаут, который будет использовать как значение по умолчанию для методов wait() .

Свойства и методы класса:

  • wait(timeout=None)
  • Блокирует работу потока до тех пор, пока не будет получено уведомление либо не пройдет время указанное в timeout.
  • Переводит Barrier в исходное (пустое) состояние. Потокам, ожидающим уведомления, будет передано исключение BrokenBarrierError .
  • Останавливает работу барьера, переводит его в состояние “разрушен” ( broken ). Все текущие и последующие вызовы метода wait() будут завершены с ошибкой с выбросом исключения BrokenBarrierError .
  • Количество потоков, которое нужно для достижения барьера.
  • Количество потоков, которое ожидает срабатывания барьера.
  • Значение флага равное True указывает на то, что барьер находится в “разрушенном” состоянии.

Пример работы с классом Barrier :

Результат работы программы:

Данный объект синхронизации может применяться в случаях когда необходимо дождаться результатов работы всех потоков (как в примере выше), либо для синхронизации процесса инициализации потоков, когда перед стартом их работы требуется, чтобы все потоки выполнили процедуру инициализации.

P.S.

Делаем свой таймер на Python

Отличия и особенности

JavaScript прекрасен тем, что его можно запустить в консоли любого современного браузера. Это для него родная среда, и JS легко работает со страницами, объектами на ней, вкладками браузера и всем, что с ним связано.

Python — более универсальный язык, который работает не только с браузерами, поэтому для него нужен отдельный интерпретатор. Интерпретатор — это программа, которая берёт исходный код и выполняет команду за командой. Вы можете написать отличный код, но чтобы его исполнить, вам всегда нужен будет интерпретатор.

Есть два способа запустить Python-код:

Минусы: так как это онлайн-сервис, им пользуется одновременно много человек, поэтому быстродействия от него ждать не стоит. С подключением внешних модулей тоже могут возникнуть проблемы, но с этим можно разобраться, если потратить немного времени.

Сейчас мы напишем таймер с оглядкой на онлайновый сервис. А отдельно ещё расскажем об установке.

Исходный код на JavaScript

Что мы здесь сделали:

Простая реализация на Python

Модуль в Python — это уже готовый python-файл, где собраны запчасти, которые помогают решать какую-то узкую задачу: функции и классы. Например, замерять время, работать с математическими функциями или календарём.

Чтобы сделать паузу, используют команду time.sleep(). Time — это название модуля, который мы подключили, а sleep — функция, которая находится внутри модуля. Её задача — подождать нужное количество секунд, а потом продолжить выполнение программы.

Что дальше: многозадачность и оптимизация

Наша программа уже работает как нужно, но её можно улучшить. Дело в том, что ставить весь код на паузу — не самое удачное решение с точки зрения производительности. Представьте, что вам нужно поставить себе несколько напоминаний на разное время. С таким подходом нам придётся выяснять, какое сработает раньше, потом корректировать время паузы для следующего напоминания и так далее.

Можно сделать так: выносить напоминания в отдельные потоки. Это как подпрограмма, которая работает параллельно с нашей программой и не сильно зависит от неё. Это позволит не ждать первого события, а запускать их одновременно. Но про всё это — в следующем материале.

Модуль Python timeit — это простой интерфейс для быстрого измерения времени выполнения небольших блоков кода.

Когда вы создаете приложение, вы можете задаться вопросом, как этот блок кода будет работать, и захотите протестировать его в различных сценариях.

Для этого модуль timeit предоставляет очень простое решение этой проблемы. Давайте посмотрим, как мы можем использовать это для синхронизации наших фрагментов кода.

Python модуль Timeit

Мы рассмотрим как интерфейс командной строки, так и вызываемый интерфейс.

Python timeit — интерфейс командной строки

Интерфейс командной строки очень похож на интерфейс запуска программы Python.

Вам необходимо импортировать внешний модуль timeit с помощью опции -m и применить его к вашему коду.

Это запустит фрагмент, переданный в виде строки, с использованием timeit .

По умолчанию это будет запускать код 1 миллион раз в Linux и 20 миллионов раз в Windows и измерять лучшее время среди этих значений. Ниже приведены результаты моей системы Linux.

Timeit Cli По Умолчанию

Обратите внимание, что если у вас уже есть цикл for в вашем фрагменте, модуль гарантирует, что общее количество итераций близко к 1 миллиону, поэтому весь ваш цикл не будет выполняться 1 миллион раз.

Timeit пример

Мы также можем использовать timeit через интерпретатор Python и импортировать его, используя:

Чтобы узнать время выполнения, передайте код в виде строки в timeit.timeit() .

Мы можем контролировать количество итераций с помощью параметра number .

Использование модуля

Давайте теперь посмотрим, как мы можем использовать timeit для timeit времени сниппета внутри нашей программы.

Что, если ваш код требует предварительной настройки? А если вам тоже нужно импортировать определенные модули?

Что ж, решение этой проблемы — использовать блок кода настройки, который выполнит всю необходимую работу по настройке всех необходимых модулей и переменных.

Написать блок настройки очень просто. Вы просто пишете любой код, который вам нужен, и передаете его в виде строки в переменную.

После этого вы можете написать свой основной блок кода и передать его timeit.timeit() , используя параметры setup и stmt .

timeit гарантирует, что настройка будет выполнена до измерения вашего основного цикла, поэтому он выполняется только один раз.

Этот код пытается получить все подмассивы из начального элемента массива numpy. Обратите внимание, что блок настройки запускается только один раз.

Сравните производительность блоков кода

Мы можем легко сравнить производительность нескольких блоков кода с помощью timeit .

Мы будем использовать для этой цели таймер, используя timeit.default_timer() .

Время, затрачиваемое на блок кода, будет текущим временем минус начальное время, взятое за эталон, которое вы можете передавать через переменные.

Давайте протестируем 2 функции в массиве numpy range() и np.arange() и посмотрим, как они сравниваются.

Таким образом, мы могли легко использовать timeit для сравнения производительности различных функций.

Время для конкретной функции

Мы также можем рассчитать время выполнения определенной функции в сценарии, не выполняя другие блоки кода.

Я хотел бы знать, как установить временную задержку в Python script.

ОТВЕТЫ

Ответ 1

Вот еще один пример, когда что-то выполняется примерно раз в минуту:

Ответ 2

Вы можете использовать функцию sleep() в модуле time . Может принимать аргумент с плавающей точкой для разрешения менее секунды.

Ответ 3

Пожалуйста, прочтите это, что может помочь вам в дальнейшем:

Попробуйте функцию сна в модуле времени.

И поставить это в while циклы и оператор будет выполняться только на минуту. Это позволяет запускать выражение в заранее определенные промежутки времени, независимо от того, как долго команда принимает ( до тех пор, как он занимает меньше минуты или 5 или 60 или как там у вас установлено) Например, я хотел запускать пинг раз в минуту. Если я просто time.sleep(60) или time.sleep(45) даже, пинг не всегда будет занимать одинаковое количество времени. Вот код :)

[5] просто извлекает секунды из возвращаемого значения time.localtime() .

Самое замечательное в time.sleep - он поддерживает числа с плавающей запятой!

Дополнительная информация

Ответ 4

В одной теме я предлагаю функцию сна:

Эта функция фактически приостанавливает обработку потока, в котором она вызывается операционной системой, что позволяет другим потокам и процессам выполняться во время сна.

Используйте его для этой цели или просто для того, чтобы отложить выполнение функции. Например:

"Ура!" печатается через 3 секунды после того, как я нажму Enter .

Пример использования sleep с несколькими потоками и процессами

Опять же, sleep приостанавливает ваш поток - он использует практически нулевую вычислительную мощность.

Чтобы продемонстрировать, создайте такой скрипт (сначала я попытался сделать это в интерактивной оболочке Python 3.5, но по какой-то причине party_later не удалось найти функцию party_later ):

Пример вывода из этого скрипта:

Многопоточность

Вы можете вызвать функцию, которая вызывается позже в отдельном потоке с Timer заправочной объекта:

Пустая строка показывает, что функция распечатана по моему стандарту, и мне пришлось нажать Enter , чтобы убедиться, что я был в приглашении.

Достоинством этого метода является то, что пока ожидал поток Timer , я мог делать другие вещи, в этом случае, нажав Enter один раз - до выполнения функции (см. Первое пустое приглашение).

В многопроцессорной библиотеке нет соответствующего объекта. Вы можете создать его, но, вероятно, по какой-то причине его не существует. Подпоток имеет гораздо больше смысла для простого таймера, чем целый новый подпроцесс.

Ответ 5

Немного веселья с сонным генератором.

Вопрос касается временной задержки. Это может быть фиксированное время, но в некоторых случаях нам может потребоваться задержка, измеренная с последнего времени. Вот одно из возможных решений:

Ситуация может заключаться в том, что мы хотим делать что-то как можно last_time , и мы не хотим беспокоиться о всех last_time , next_time за нашим кодом.

Генератор зуммера

Следующий код (sleepy.py) определяет генератор buzzergen :

Вызов регулярного buzzergen

И запустив его, мы видим:

Мы также можем использовать его непосредственно в цикле:

И запустив его, мы увидим:

Как мы видим, этот зуммер не слишком жесткий и позволяет нам догнать регулярные сонные интервалы, даже если мы проспали и вышли из обычного графика.

Ответ 6

Задержки также могут быть реализованы с использованием следующих методов.

Вторым методом задержки будет использование метода неявного ожидания:

Третий метод более полезен, когда вам нужно подождать, пока определенное действие не будет выполнено или пока не будет найден элемент:

Ответ 7

Библиотека tkinter в стандартной библиотеке Python представляет собой интерактивный инструмент, который можно импортировать. В принципе, вы можете создавать кнопки и поля, всплывающие окна и прочее, которые отображаются в виде окон, которыми вы управляете с помощью кода.

Если вы используете tkinter, НЕ ИСПОЛЬЗУЙТЕ TIME.SLEEP() потому что это TIME.SLEEP() вашу программу. Это случилось со мной. Вместо этого используйте root.after() и замените значения на сколько секунд, с миллисекундами. Например, time.sleep(1) эквивалентен root.after(1000) в tkinter.

В противном случае, time.sleep() , о чем многие ответы указывают, это путь.

Ответ 8

Задержки выполняются с помощью библиотеки времени, в частности, функции time.sleep() .

Чтобы просто подождать секунду:

Это работает, потому что, делая:

Вы извлекаете функцию сна только из библиотеки времени, что означает, что вы можете просто вызвать ее с помощью:

Вместо того, чтобы печатать

Который неловко долго печатать.

С этим методом вы не получите доступ к другим функциям библиотеки времени, и у вас не будет переменной с именем sleep . Но вы можете создать переменную с именем time .

Выполнение from [library] import [function] (, [function2]) - это замечательно, если вам нужны только определенные части модуля.

Вы также можете сделать это следующим образом:

и вы будете иметь доступ к другим функциям библиотеки времени, таким как time.clock() до тех пор, пока вы вводите time.[function]() , но вы не можете создать переменную time, потому что она перезапишет импорт. Решение этого сделать

что позволит вам ссылаться на библиотеку времени как t , что позволит вам сделать:

Это работает в любой библиотеке.

Ответ 9

Есть 5 известных мне методов: time.sleep() , pygame.time.wait() , matplotlib pyplot.pause() , .after() и driver.implicitly_wait() .

time.sleep() (не использовать при использовании Tkinter):

pygame.time.wait() (не рекомендуется, если вы не используете окно pygame, но вы можете выйти из окна мгновенно):

Пример функции pyplot.pause() (не рекомендуется, если вы не используете график, но вы можете выйти из графика мгновенно):

Метод .after() (лучше всего с Tkinter):

Наконец, метод driver.implicitly_wait() (селен):

Ответ 10

Лучший способ задержать время в Python - использовать библиотеку time . Как это:

Просто замените 10 на количество секунд, которое вы хотите отложить. Вы можете использовать такие форматы, как '10.1 ',' 5.07 'и т.д.

Не рекомендуется использовать это с Tkinter

Ответ 11

Ответ 12

asyncio.sleep

Обратите внимание, что в последних версиях Python (Python 3.4 или выше) вы можете использовать asyncio.sleep . Это связано с асинхронным программированием и асинхронностью. Проверьте следующий пример:

Мы можем подумать, что он будет "спать" в течение 2 секунд для первого метода, а затем 3 секунды во втором методе, всего 5 секунд времени выполнения этого кода. Но он напечатает:

Рекомендую прочитать официальную документацию Asyncio для более подробной информации.

Ответ 13

Если вы хотите установить задержку в скрипте Python:

Используйте time.sleep или Event().wait следующим образом:

Зачем использовать более поздний подход?

  • не останавливает выполнение всего сценария. (кроме функции, которую вы передаете)
  • После запуска таймера вы также можете остановить его, выполнив timer_obj.cancel() .

Ответ 14

В то время как все остальные предложили модуль time де-факто, я решил поделиться другим методом, использующим функцию matplotlib pyplot , pause .

Пример

Обычно это используется для предотвращения исчезновения графика сразу после его построения или для создания грубой анимации.

Это сэкономит вам import если вы уже импортировали matplotlib .

Ответ 15

Это простой пример задержки:

Другой, в Tkinter:

Ответ 16

Вы можете использовать метод сна во временном пакете, чтобы задержать выполнение программы на Python

Ответ 17

Чтобы установить временную задержку, вы должны импортировать модуль time . И с этим модулем вам нужно только написать:

Например, если вы хотите поставить временную задержку за секунду до того, как компьютер выполнит другую строку, вы должны поместить:

Ответ 18

Я искал предыдущие ответы, и я просто хотел бы основываться на них.

Я часто хотел создать эффект печати, вот как вы можете это сделать (Python 3):

Я надеюсь, что это помогло вам в некотором роде.

Ответ 19

Вы можете создать временную задержку в Python, используя два простых подхода, основанных на time.sleep() .

Ответ 20

Вы также можете попробовать это:

теперь оболочка не будет падать или не реагировать

Ответ 21

вот очень простой пример

Ответ 22

Если у вас установлен autopygui, вы можете использовать:

И общее время паузы будет time1 секунд

Ответ 23

Если вам нужно плавать задержки, вы можете использовать sleep :

Я кодирую Марио, используя Pygame, и я кодирую блоки прямо сейчас. Я хочу сделать таймер, чтобы, когда я нажимаю на блок через секунду, блок возвращается в исходное положение для создания анимации удара. Проблема заключается в том, что при таймере сна он замораживает всю игру на время таймера. Мне нужен код для запуска и через секунду этот предыдущий блок кода, чтобы сработать.

Я пытался использовать сон, чтобы сделать таймер, но он зависает всю игру. Кто-нибудь может дать мне немного знаний? Спасибо!

Читайте также: