Python:每天随机执行一个函数

Python:每天随机执行一个函数,python,python-3.x,datetime,compare,epoch,Python,Python 3.x,Datetime,Compare,Epoch,我想在设定的时间段内每天随机执行一个函数。以下是我目前掌握的情况: def get_epochtime(dt=datetime.now()): EPOCH = datetime(1970, 1, 1) return (dt - EPOCH).total_seconds() def get_todays_run_schedule(runs_per_day, run_between): now = datetime.now() window_start = now.

我想在设定的时间段内每天随机执行一个函数。以下是我目前掌握的情况:

def get_epochtime(dt=datetime.now()):
    EPOCH = datetime(1970, 1, 1)
    return (dt - EPOCH).total_seconds()

def get_todays_run_schedule(runs_per_day, run_between):
    now = datetime.now()
    window_start = now.replace(hour=run_between[0])
    window_end   = now.replace(hour=run_between[1])
    the_schedule = [ get_epochtime(radar.random_datetime(start=window_start, stop=window_end)) for t in range(randint(runs_per_day[0], runs_per_day[1])) ]
    the_schedule.sort()
    print("Today I will run %s times" % len(the_schedule))
    for run_at in the_schedule:
        print("I will run at " + time.strftime("%Y-%m-%d %H:%M", time.localtime(run_at)))
    return the_schedule

# we will run between 2 and 4 times per day between the hours of 10 AM and 5 PM.
schedule = get_todays_run_schedule((2, 4), (10, 17))

while(True):
    now = datetime.now()
    nowsecs = get_epochtime(now)
    if now.hour == 0 and now.minute == 0 and now.second == 0:
        schedule = get_todays_run_schedule()
    if nowsecs in schedule:
        execute_my_function
    sleep(1)
基本上,我们的想法是,在午夜和第一次运行时,我们会提出一个运行计划,它是一个历元时间列表,其长度介于两个提供的整数之间。我们每秒钟检查一次时间,如果当前时间在运行时间列表中,则执行函数。最后,我们睡到下一秒


然而,它根本不起作用。我怀疑这可能是因为我的datetime对象不知何故包含了微秒,这使比较失去了意义,但这可能是因为我不了解python中日期-时间比较的本质。

确实,微秒对您来说是个问题,在这里,列表中的对象和现在的对象都有微秒,并且只运行一次/秒的循环,这些NOW与事件时间戳完全匹配的可能性非常小

但是,即使通过将“现在”和列表中的值都截断为秒来修复该问题,这仍然无法解决问题,只会使其成为更难调试的间歇性问题。想想如果你在15:25:26有一个事件,你会在15:25:25.907开始循环。你把它截成15:25:25,查一下,它不在那里。然后你睡了大约一秒钟,现在打电话,你得到,比如说,15:25:27.033。你把它截成15:25:27,查一下,它也不在那里

因为您已经对列表进行了排序,所以可以做一些更简单的事情,我将在下面演示。但是首先:当我们在这里的时候,datetime对象的全部意义在于,它们可以直接进行时间比较、算术等,因此您不需要使用诸如get_epochtime之类的东西将所有内容转换为数字

显然,您还需要更改get_todays_run_schedule以返回datetime对象列表,而不是浮点数列表,这样做,但您应该能够找到答案

另外,请注意,通过这种方式,我们总是知道下一个事件发生的时间,因此我们不需要在sleep1上循环,并在电脑使用电池时保持每秒唤醒电脑。你可以只睡时间表[0]-现在有下一个事件时,或睡到午夜时没有。或者,更简单地说,当日程表变空时,生成明天的日程表,然后一直睡到日程表[0]

事实上,如果您仔细想想,您应该能够想出如何将其转化为以下形式的循环:

while True:
    schedule = make_today_or_tomorrow_schedule()
    for event in schedule:
        while datetime.now() < event:
            sleep(event - datetime.now())
        execute_my_function

您几乎肯定不想在时间戳中使用这样的签入检查。微秒可能是一个问题,但即使您将now和set都截断为整数秒,也不会阻止循环在15:25:25.907和15:25:27.033运行,并完全错过15:25:26的预定事件。另外,作为补充说明,您不需要使用get\u epochtime将datetime对象转换为数字;你可以直接比较它们,对它们进行日期运算,等等。谢谢@abarnert,我也这么怀疑。你能给我更多关于如何实现这一点的细节吗?我已经写了一个答案,但首先你是作为一个学习练习,还是为了完成一些实际任务?因为有预先存在的、经过良好测试的、灵活的库为您处理所有这些内容。不,这不是一个编程练习,而是一个现实世界的问题。我宁愿使用图书馆。但是我的google foo无法应对@abarnert的挑战,因此使用了雷达库等。我喜欢上一个例子@abarnert的简洁
while True:
    schedule = make_today_or_tomorrow_schedule()
    for event in schedule:
        while datetime.now() < event:
            sleep(event - datetime.now())
        execute_my_function