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

时间:2018-03-25 22:18:54

标签: 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.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)

基本上这个想法是在午夜和第一次运行时,我们提出了一个运行时间表,它是一个纪元时间列表,其长度在两个提供的整数之间。每秒我们检查时间,如果当前时间在运行时间列表内,我们执行我们的功能。最后,我们一直睡到下一秒。

然而,它根本不起作用。我怀疑这可能是因为我的日期时间对象在某种程度上包括微秒,这会丢掉比较,但可能是因为我不了解python中日期时间比较的性质。

1 个答案:

答案 0 :(得分:1)

确实,微秒在这里对你来说是一个问题 - 列表中的对象和now都将有微秒,并且只运行一次/秒的循环,任何这些对象的可能性{{ 1}}与事件时间戳完全匹配非常小。

但即使您通过将now和列表中的值都截断为秒来解决问题,仍然无法解决问题,它只会使其成为一个难以调试的间歇性问题。考虑如果您在15:25:26发生事件,并在15:25:25.907开始循环,会发生什么。你将其截断到15:25:25,查找它,它不存在。然后你睡了大约一秒钟,然后打电话给now,你得到15:25:27.033。你把它截断到15:25:27,查找它,它也不存在。

由于你已经对列表进行了排序,你可以做一些更简单的事情,我将在下面演示。但首先:虽然我们正处于这种状态,但now()对象的全部意义在于它们可以直接进行时间比较,算术等,因此您无需将所有内容转换为数字,例如您的{ {1}}。

datetime

(显然你还需要更改get_epochtime以返回yesterday = datetime.today() - datetime.timedelta(days=1) while True: now = datetime.now() if now.date() > yesterday: schedule = get_todays_run_schedule() yesterday = now.date() while schedule and now >= schedule[0]: del schedule[0] execute_my_function sleep(1) 个对象列表而不是浮动列表来这样做,但你应该能够弄明白。 )

另外,请注意这一点,我们总是知道下一个事件发生之前的时间,因此我们不需要在get_todays_run_schedule周围循环,并且在电池上每秒钟都会一直唤醒电脑。当有下一个事件时你可以datetime,或者在没有事件时睡到午夜。或者,更简单地说,当sleep(1)变空时生成明天的计划,然后只是睡到sleep(schedule[0] - now)

事实上,如果你考虑一下,你应该能够想出如何将它变成这种形式的循环:

schedule