Python每10秒运行一个程序,datetime.now()会改变行为

2024-04-26 21:52:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在测试一个程序,每N秒做一次,但我遇到了一个奇怪的问题

如果我使用这样简单的方法:

import time

def main():
    start_t = time.time()

    while(True):
        if (time.time()-start_t)%10 == 0:
            print("Test")

if __name__ == "__main__":
    main()

程序按预期工作,即每10秒打印一次“测试”

但是,我做了一个小修改,因为我需要在每次迭代时检查当前日期…如果我将程序更改为:

import time
from datetime import datetime


def main():
    start_t = time.time()
    path_screenshots = "screenshots"

    while(True):
        path_screenshots_today = f"{path_screenshots}/{datetime.now().strftime('%Y_%m_%d')}/"
        if (time.time()-start_t)%10 == 0:
            print(f"Checking folder {path_screenshots_today}...")

if __name__ == "__main__":
    main()

我希望该程序再次每隔10秒打印一次“Checking folder{path_screenshots_today}”,但它一直在运行,没有打印任何内容。 我知道操作的结果(time.time()-start_t)%10永远不会精确地等于0,这可能会产生问题……但是,为什么它在第一种情况下都能工作呢


Tags: pathnameimport程序truetodaydatetimeif
3条回答

第一种情况之所以有效,是因为检查时间的频率足够高,而第二种情况则不会发生,因为字符串格式设置会引入延迟。更可靠的方法如下所示:

start_t = time.time()
while True:
    path_screenshots_today = f"{path_screenshots}/{datetime.now().strftime('%Y_%m_%d')}/"
    tt = time.time()
    if tt - start_t >= 10:
        print(f"Checking folder {path_screenshots_today}...")
        start_t = tt  # set last check time to "now"

更好的办法是:

while True:
    path_screenshots_today = f"{path_screenshots}/{datetime.now().strftime('%Y_%m_%d')}/"
    print(f"Checking folder {path_screenshots_today}...")
    time.sleep(10)

这避免了“忙等待”,即保持CPU疯狂运行

我怀疑它在第一种情况下是有效的,因为循环运行得足够快,以至于它恰好排成一行。通过创建path_screenshots_today(特别是datetime.now()调用)产生的延迟导致它不能经常排队。要实际执行您想要的操作,请尝试:

import time
from datetime import datetime


def main():
    last = time.time()
    path_screenshots = "screenshots"

    while True:
        path_screenshots_today = f"{path_screenshots}/{datetime.now().strftime('%Y_%m_%d')}/"
        if time.time() - last >= 10:
            last = time.time()
            print(f"Checking folder {path_screenshots_today}...")

if __name__ == "__main__":
    main()

这是一个巧合的频率检查发生。如果您实际循环并打印您的值,您会注意到它是浮点值:

    while(True):
        print('Current value is, ', (time.time()-start_t)%10)

您将看到如下输出:

Current value is,  0.45271849632263184
Current value is,  0.45272231101989746

考虑到您在循环中所做的工作非常少,当当前值正好是时,您很有可能会碰巧进行该计算。但是,当您添加一些额外的计算时,即使只是datetime中的字符串格式,循环的每次迭代都将花费更长的时间,您可能很高兴跳过0.0

严格来说,在将值与0进行比较之前,应该将值转换为int。例如,int((time.time() - start_t) % 10) == 0。这将持续一整秒钟,直到模数值再次不为零,在第一次为真后的一秒钟

然而,一个更好的解决方案可能只是使用time.sleep()函数。您可以调用time.sleep以睡眠几秒钟:

time.sleep(10)   # Sleep for 10 seconds

相关问题 更多 >