Вот как сделать один выстрел в периодическое событие, например, с sched
: если функция должна создать свой собственный планировщик и быть единственной вещью, работающей в ее потоке:
def tick(self, display, alarm_time, scheduler=None):
# make a new scheduler only once & schedule this function immediately
if scheduler is None:
scheduler = sched.scheduler(time.time, time.sleep)
scheduler.enter(0, 1, self.tick, ([display, alarm_time, scheduler]))
scheduler.run()
# reschedule this function to run again in a minute
scheduler.enter(1, 1, self.tick, (display, alarm_time, scheduler]))
# do whatever actual work this function requires, e.g.:
self.updateTime(display)
Если другие события также должны быть запланированы в том же потоке, то планировщик должен быть создан и находиться в «другом месте» - вышеприведенная часть if
может быть преобразована в другой метод, например ::10000
def scheduleperiodic(self, method, *args):
self.scheduler = sched.scheduler(time.time, time.sleep)
self.scheduler.enter(0, 1, method, args)
# whatever else needs to be scheduled at start, if any, can go here
self.scheduler.run()
def tick(self, display, alarm_time):
# reschedule this function to run again in a minute
self.scheduler.enter(60, 1, self.tick, (display, alarm_time))
# do whatever actual work this function requires, e.g.:
self.updateTime(display)
Опять же, разумеется, и, как всегда, с sched
, пока работает планировщик, он (и обратные вызовы запланированных событий) «захватит» рассматриваемый поток (поэтому вам нужно будет отделить отдельный поток для этого, если вам нужно, чтобы другие вещи происходили одновременно).
Если вам нужно использовать этот вид идиомы во многих функциях, он может быть преобразован в декоратор, но это несколько замаскирует основную простоту идиомы, поэтому я предпочитаю это простое, открытое использование. Кстати, обратите внимание, что time.time и time.sleep используют секунды, а не минуты, в качестве единицы времени, поэтому вам нужно 60, а не одна, чтобы указать «минуту спустя»; -).