Каков наилучший способ повторно выполнять функцию каждые x секунд в Python? - PullRequest
206 голосов
/ 24 января 2009

Я хочу многократно выполнять функцию в Python каждые 60 секунд навсегда (точно так же, как NSTimer в Задаче C). Этот код будет работать как демон, и он по сути похож на вызов сценария python каждую минуту с использованием cron, но без необходимости его настройки пользователем.

В этом вопросе о cron, реализованном в Python , решение, по-видимому, эффективно просто sleep () в течение x секунд. Мне не нужны такие расширенные функциональные возможности, поэтому, возможно, что-то подобное будет работать

while True:
    # Code executed here
    time.sleep(60)

Есть ли возможные проблемы с этим кодом?

Ответы [ 15 ]

1 голос
/ 24 марта 2017

Один из возможных ответов:

import time
t=time.time()

while True:
    if time.time()-t>10:
        #run your task here
        t=time.time()
0 голосов
/ 28 августа 2018
    ''' tracking number of times it prints'''
import threading

global timeInterval
count=0
def printit():
  threading.Timer(timeInterval, printit).start()
  print( "Hello, World!")
  global count
  count=count+1
  print(count)
printit

if __name__ == "__main__":
    timeInterval= int(input('Enter Time in Seconds:'))
    printit()
0 голосов
/ 14 марта 2018

Я использую метод Tkinter after (), который не «крадет игру» (как модуль sched , который был представлен ранее), то есть он позволяет другим вещам работать параллельно:

import Tkinter

def do_something1():
  global n1
  n1 += 1
  if n1 == 6: # (Optional condition)
    print "* do_something1() is done *"; return
  # Do your stuff here
  # ...
  print "do_something1() "+str(n1)
  tk.after(1000, do_something1)

def do_something2(): 
  global n2
  n2 += 1
  if n2 == 6: # (Optional condition)
    print "* do_something2() is done *"; return
  # Do your stuff here
  # ...
  print "do_something2() "+str(n2)
  tk.after(500, do_something2)

tk = Tkinter.Tk(); 
n1 = 0; n2 = 0
do_something1()
do_something2()
tk.mainloop()

do_something1() и do_something2() могут работать параллельно и с любым интервалом скорости. Здесь 2-й будет выполнен вдвое быстрее. Обратите внимание, что я использовал простой счетчик в качестве условия для завершения любой функции. Вы можете использовать любое другое условие, которое вам нравится, или нет, если вы хотите выполнить функцию до завершения программы (например, часы).

0 голосов
/ 29 сентября 2017

Например, показать текущее местное время

import datetime
import glib
import logger

def get_local_time():
    current_time = datetime.datetime.now().strftime("%H:%M")
    logger.info("get_local_time(): %s",current_time)
    return str(current_time)

def display_local_time():
    logger.info("Current time is: %s", get_local_time())
    return True

# call every minute
glib.timeout_add(60*1000, display_local_time)
0 голосов
/ 21 февраля 2017

Я использую это, чтобы вызвать 60 событий в час, при этом большинство событий происходит с одинаковым количеством секунд после целой минуты:

import math
import time
import random

TICK = 60 # one minute tick size
TICK_TIMING = 59 # execute on 59th second of the tick
TICK_MINIMUM = 30 # minimum catch up tick size when lagging

def set_timing():

    now = time.time()
    elapsed = now - info['begin']
    minutes = math.floor(elapsed/TICK)
    tick_elapsed = now - info['completion_time']
    if (info['tick']+1) > minutes:
        wait = max(0,(TICK_TIMING-(time.time() % TICK)))
        print ('standard wait: %.2f' % wait)
        time.sleep(wait)
    elif tick_elapsed < TICK_MINIMUM:
        wait = TICK_MINIMUM-tick_elapsed
        print ('minimum wait: %.2f' % wait)
        time.sleep(wait)
    else:
        print ('skip set_timing(); no wait')
    drift = ((time.time() - info['begin']) - info['tick']*TICK -
        TICK_TIMING + info['begin']%TICK)
    print ('drift: %.6f' % drift)

info['tick'] = 0
info['begin'] = time.time()
info['completion_time'] = info['begin'] - TICK

while 1:

    set_timing()

    print('hello world')

    #random real world event
    time.sleep(random.random()*TICK_MINIMUM)

    info['tick'] += 1
    info['completion_time'] = time.time()

В зависимости от реальных условий вы можете получить отметки длины:

60,60,62,58,60,60,120,30,30,60,60,60,60,60...etc.

но через 60 минут у вас будет 60 тиков; и большинство из них будет происходить с правильным смещением в ту минуту, которую вы предпочитаете.

В моей системе я получаю типичный дрейф <1/20 секунды, пока не возникнет необходимость в коррекции. </p>

Преимущество этого метода - разрешение смещения часов; что может вызвать проблемы, если вы делаете такие вещи, как добавление одного элемента за тик, и ожидаете, что 60 элементов добавляются в час. Отказ от учета дрейфа может привести к тому, что вторичные индикаторы, такие как скользящие средние, будут рассматривать данные слишком глубоко в прошлом, что приведет к ошибочному выводу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...