- Тайминг в Python
- Ключевые термины
- Задержка – это…
- Класс Timer
- Функции
- Time.Time
- Ctime()
- Sleep
- Класс struct_time
- Реализация Sleep
- Adding Timeouts to Functions Using Wrapt Timeout Decorator
- A short guide on how to implement timeouts when calling functions in Python
- 1. Installing the wrapt_timeout_decorator
- 2. Using the wrapt_timeout_decorator
- 2.1 Example without timeout
- 2.2. Example with timeout
- 3. Conclusion
Тайминг в Python
Python – язык программирования, который можно отнести к общему назначению. С его помощью пишут как бизнес-софт, так и развлекательный (игровой) контент. Это отличное решение для новичков в разработке. Относится к объектно-ориентированному типу.
В данной статье будет рассказано о том, что собой представляет задержка в Python, как использовать time (таймер), для чего все это нужно. Информация пригодится даже опытным разработчикам, которые планируют работу со временем в будущей утилите.
Ключевые термины
Пытаясь освоить Python, программеру потребуется выучить немало теории. Вот базовые термины, без которых время и остальные компоненты кодификаций применять на деле не получится:
- Ключевое слово – зарезервированное системой слово или фраза. Обозначает действие, операцию, функцию. Ключевики не могут выступать в виде имен переменных.
- Переменная – именованная ячейка памяти, которую можно изменять, сохранять и считывать.
- Алгоритм – последовательность действий, набор правил, помогающих решать те или иные задачи.
- Класс – набор связанных между собой объектов, которые имеют общие свойства.
- Объект – комбинация переменных, констант и иных структурных единиц. Они выбираются совместно и аналогичным образом проходят обработку.
- Константа – значение, которое не будет меняться на протяжении всего выполнения утилиты.
- Тип данных – классификация информации определенного вида.
- Массив – множество данных. Они предварительно группируются.
Огромную роль в Python играют ключевые слова. Их необходимо либо запоминать, либо заучивать, либо держать где-то поблизости справочник с соответствующими данными. Иначе при объявлении переменных не исключены проблемы.
Задержка – это…
Задержка – термин, который применим ко времени. Он встречается и в обыденной жизни. Это – ситуация, когда что-то происходит или должно осуществиться не сразу. Пример – после наступления каких-то обстоятельств.
В программировании задержка «откладывает» выполнение кода на определенное время. Часто такая потребность возникает тогда, когда нужно дождаться завершения иного процесса, чтобы задействовать далее полученный результат.
При рассмотрении многопоточных утилит, использовать таймер (timer) и время (time) нужно, чтобы дождаться завершения операции и функций из других потоков.
Класс Timer
Класс Timer () в Python отвечает за время и работу с ним «от начала по конца». Модуль, метод, используемый для задержки и всего, что с ней связано. Перед использованием оного требуется произвести импорт компонента.
Для этого подойдет запись типа import time в Python. Класс относится к модулю threading. Он создает таймер, который запускает функцию с аргументами и ключевыми значениями (kwargs). Происходит это за счет time, установленного как interval. Этот параметр указывается в секундах.
Программеру предстоит запомнить следующее:
- Запись функции с классом, отвечающего за таймаут (timeout) –
- Если args равен None (этот показатель устанавливается изначально), Python использует пустой список.
- Когда ключевое слово kwargs равен None, применяется пустой словарь.
- Класс «Таймер» представлен действием, которое нужно запускать только по прошествии конкретного промежутка времени.
- Таймер выступает в виде подкласса threading.Thread().
Все это требуется запомнить. А еще – учесть, что в процессе коддинга предстоит использовать суперкласс (super class), а также мета данные.
Функции
Рассматривая methods time, программисту требуется изучить разнообразные функции, связанные со временем. Это поможет лучше разобраться в потоках и задержках. Не стоит забывать, что при тестинге важно использовать print. Эта операция выводит результат на экран.
Time.Time
Функция Time() будет возвращать число секунд, которые прошли с начала эпохи. Для Unix-систем это – 1.01.1970. Отсчет с 12 часов ночи ровно.
Ctime()
Компонент, который будет в виде аргумента в Python принимать количество секунд, прошедших с самого начала эпохи. Результат – возврат строки по местному time.
Sleep
Отвечает за непосредственную задержку. Откладывает исполнение нынешнего потока на заданное количество секунд.
Класс struct_time
Изучая, какой метод подойдет для работы с таймерами и super class, стоит обратить внимание на struct_time. Этот объект может быть принят некоторыми функциями в упомянутом ранее модуле. При обработке оного происходит возврат.
Реализация Sleep
Когда нужный метод для работы с задержкой изучен, можно рассмотреть то, как сделать таймаут. Для этого используют super class, а также sleep. Он проходит реализацию несколькими способами:
- Через time.sleep(). Это – встроенная возможность Python. Отвечает за таймаут через модуль time. Откладывает выполнение потока на установленное количество секунд.
- Вызов с декораторами. Активируют, когда одно неудачно выполненное действие требуется запустить снова.
- В потоках. Такие ситуации требуют, чтобы приложение избегало простоя. Для этого применяют или time.sleep(), или Event.wait() из модуля threading.
- Из Async IO. Асинхронные возможности появились в Питоне, начиная с 3.4 версии. Это – тип параллельного программирования.
- В Tkinter и wxPython. Отсрочки возможны при создании пользовательских интерфейсов. При применении sleep() внутри GUI кода блокируется цикл обработки событий.
- After(). Это – метод, который погружает в сон для Tkinter. Часть стандартной библиотеки.
- CallLater. Метод для wxPython. Имеет больше виджетов и хорошо годится для нативной разработки.
А вот видео, где можно наглядно увидеть работу с таймером в Python. Лучше разобраться с этой темой, как и с языком программирования, помогут дистанционные компьютерные курсы. Программы рассчитаны на срок до года. В конце будет выдан электронный сертификат. В процессе пользователи получат не только хорошо поданный учебный материал, но и новые полезные связи. А еще – соберут портфолио для трудоустройства.
Adding Timeouts to Functions Using Wrapt Timeout Decorator
A short guide on how to implement timeouts when calling functions in Python
In this short guide, I will show how to use a handy timeout decorator for Python function to limit the execution times. This guide is based on an example that utilizes Python’s multiprocessing package.
Lately, I’ve been building a script using Beautiful Soup that scrapes similarly structured websites and identifies its chapters. These were 10-K annual reports on the SEC’s website which had to be split according to their 21 sections. To make the script as robust as possible, I’ve used the simple, yet effective, python-constraint module to make sure that the sections were identified in the correct order. This approach worked perfectly in most cases and took less than a second to execute. Unfortunately, for some cases, the constraint function caused the script to run for days until it went through all iterations. By analyzing the execution times of the constraint function, I came to the following conclusion:
A fix for this issue was simple thanks to the wrapt_timeout_decorator module. The great thing about this module is that it’s easy to use, works great with Python’s multiprocessing module, and has no problem running on Windows.
1. Installing the wrapt_timeout_decorator
You can install the wrapt_timeout_decorator module from PyPI using pip.
pip install wrapt_timeout_decorator
If you’re using Conda, I suggest downloading the source files from GitHub (https://github.com/bitranox/wrapt_timeout_decorator) and installing the module manually by running
within your active environment. You will need Python 3.5 or later for the module to work.
2. Using the wrapt_timeout_decorator
The following example is intended for Windows users. Linux users will have it easier using the wrapt_timeout_decorator because it’s not necessary to put the timeout function in a separate module. For more information on this, see the official documentation here. I haven’t tried this module in a Jupyter notebook, but I assume it will require a workaround similar to the multiprocessing package.
The example below shows how to apply a timeout on a function that is parallelized on multiple threads using the multiprocessing package.
2.1 Example without timeout
# main_program.pyfrom multiprocessing import Pool
import my_functionmy_list = [1,2,3,4,4,3,2,1]if __name__ == ‘__main__’:
num_processors = 4
p = Pool(processes = num_processors)
p.map_async(my_function.sleep_function, my_list).get()
And here is the function my_function which is parallelized across 4 threads:
# my_function.pyfrom time import sleepdef sleep_function(num):
sleep(num)
print(f'The program slept for seconds.')
The output of this program will be:
The program slept for 1 seconds.
The program slept for 2 seconds.
The program slept for 3 seconds.
The program slept for 4 seconds.
The program slept for 4 seconds.
The program slept for 3 seconds.
The program slept for 2 seconds.
The program slept for 1 seconds.
The first for 4 lines will appear 1, 2, 3, and 4 seconds after executing the program respectively. Because we’re using the map_async method, the remaining 4 lines will appear all at once after another 4 seconds have passed. The first thread waits 1 second and then takes the next available element from my_list, which is 4, and waits 4 more seconds (in total 5 seconds). The second thread waits 2 seconds, then takes the next available element from my_list, which is 3, and waits 3 more seconds (again 5 seconds in total) and so on.
2.2. Example with timeout
Imagine we want to limit the time for which the sleep_function is allowed to run. Let’s say we set this timeout to 2.5 seconds. To do this, we have to make three changes to our program.
- Apply a timeout decorator to the sleep_function.
- Carve out the timed-out sleep_function into a separate module.
- Change the my_function.py to execute this carved-out module.
Here is how the carved-out module of the timed-out function will look like:
# my_timeout_function.pyfrom time import sleep
from wrapt_timeout_decorator import *@timeout(2.5)
def timeout_sleep_function(num):
sleep(num)
print(f'The program slept for seconds.')
Using the @timeout decorator, we’ve set the limit for how long the function can run to 2.5 seconds. Apart from that, the code of the function remains unchanged.
Now we have to go back to our my_function.py module and call the newly created timeout_sleep_function from there:
# my_function.pyimport my_timeout_functiondef sleep_function(num):
try:
my_timeout_function.timeout_sleep_function(num)
except:
print('Timeout of 2.5 seconds reached!')
Because we have set a limit of 2.5 seconds for the timeout_sleep_function, the output of our main_program.py will now be:
The program slept for 1 seconds.
The program slept for 2 seconds.
Timeout of 2.5 seconds reached!
Timeout of 2.5 seconds reached!
The program slept for 1 seconds.
Timeout of 2.5 seconds reached!
The program slept for 2 seconds.
Timeout of 2.5 seconds reached!
3. Conclusion
The timeout wrapper has changed the structure of our code as follows:
- Main program main_program.py. This initializes the multiprocessing and calls the function sleep_function from the “in-between” module my_function.py. No actual changes to the code were made.
- The “in-between” module my_function.py. This calls the timed-out function timeout_sleep_function from the module my_timeout_function.py. Having this “in-between” module is necessary for Windows users.
- The module my_timeout_function.py that has the actual timed-out function timeout_sleep_function.
As you can see, using the wrapt_timeout_decorator to limit execution times of functions is relatively simple. I was able to add a timeout to my 10-K annual report section separator quickly without a lot of changes to the original code. This small addition, however, caused a major reduction in execution times.
Here is a final wrap-up of the example using the wrapt_timeout_decorator module:
#----------------------------
# main_program.pyfrom multiprocessing import Pool
import my_function_timeoutmy_list = [1,2,3,4,4,3,2,1]if __name__ == '__main__':
num_processors = 4
p = Pool(processes = num_processors)
p.map_async(my_function.sleep_function, my_list).get()#----------------------------
# my_function.pyimport my_timeout_functiondef sleep_function(num):
try:
my_timeout_function.timeout_sleep_function(num)
except:
print('Timeout of 2 seconds reached!')#----------------------------
# my_timeout_function.pyfrom time import sleep
from wrapt_timeout_decorator import *@timeout(2.5)
def timeout_sleep_function(num):
sleep(num)
print(f'The program slept for seconds.')
I hope this little guide will help you apply timeouts to functions in Python.