Если вы хотите, чтобы неблокирующий способ выполнял вашу функцию периодически, вместо блокирующего бесконечного цикла, я бы использовал потоковый таймер. Таким образом, ваш код может продолжать работать и выполнять другие задачи, при этом ваша функция вызывается каждые n секунд. Я часто использую эту технику для распечатки информации о ходе выполнения длинных задач, интенсивно использующих CPU / Disk / Network.
Вот код, который я разместил в похожем вопросе с элементами управления start () и stop ():
from threading import Timer
class RepeatedTimer(object):
def __init__(self, interval, function, *args, **kwargs):
self._timer = None
self.interval = interval
self.function = function
self.args = args
self.kwargs = kwargs
self.is_running = False
self.start()
def _run(self):
self.is_running = False
self.start()
self.function(*self.args, **self.kwargs)
def start(self):
if not self.is_running:
self._timer = Timer(self.interval, self._run)
self._timer.start()
self.is_running = True
def stop(self):
self._timer.cancel()
self.is_running = False
Использование:
from time import sleep
def hello(name):
print "Hello %s!" % name
print "starting..."
rt = RepeatedTimer(1, hello, "World") # it auto-starts, no need of rt.start()
try:
sleep(5) # your long-running job goes here...
finally:
rt.stop() # better in a try/finally block to make sure the program ends!
Особенности:
- Только стандартная библиотека, без внешних зависимостей
start()
и stop()
безопасно вызывать несколько раз, даже если таймер уже запущен / остановлен
- вызываемая функция может иметь позиционные и именованные аргументы
- Вы можете изменить
interval
в любое время, оно вступит в силу после следующего запуска. То же самое для args
, kwargs
и даже function
!