Python脚本每天在同一时间做某事[重复]

Posted

技术标签:

【中文标题】Python脚本每天在同一时间做某事[重复]【英文标题】:Python script to do something at the same time every day [duplicate] 【发布时间】:2013-02-11 20:09:57 【问题描述】:

我有一个长时间运行的 python 脚本,我想在每天早上 1:00 做一些事情。

我一直在查看 sched 模块和 Timer 对象,但我不知道如何使用它们来实现这一点。

【问题讨论】:

也可以考虑通过cron运行一个单独的脚本。 是的,应该说,无权访问cron 【参考方案1】:

我还花了很多时间寻找在 01:00 启动一个简单的 Python 程序。出于某种原因,我无法让 cron 启动它,而且 APScheduler 对于本应简单的事情来说似乎相当复杂。时间表 (https://pypi.python.org/pypi/schedule) 似乎是正确的。

你必须安装他们的 Python 库:

pip install schedule

这是从他们的示例程序修改而来的:

import schedule
import time

def job(t):
    print "I'm working...", t
    return

schedule.every().day.at("01:00").do(job,'It is 01:00')

while True:
    schedule.run_pending()
    time.sleep(60) # wait one minute

您需要将自己的函数替换为作业并使用 nohup 运行它,例如:

nohup python2.7 MyScheduledProgram.py &

重启后别忘了重新启动。

【讨论】:

以后看到这个帖子的人,希望他们明白这是生产代码的正确解决方案,而不是公认的解决方案。 这可以在 mac、linux 和 windows 上运行吗?或者这个脚本需要一些修改? @yeaske 这个库在 Windows 上也很好用! 它可以工作,但While block 阻止其他代码行运行,有什么办法解决这个问题吗? 警告:如果您同时运行多个应用程序,例如Flask 应用程序,此调度程序将阻塞。如果你想并行或在后台作为守护进程运行进程,你仍然需要使用 APScheduler 之类的东西。所以我不认为这总是正确的解决方案。【参考方案2】:

你可以这样做:

from datetime import datetime
from threading import Timer

x=datetime.today()
y=x.replace(day=x.day+1, hour=1, minute=0, second=0, microsecond=0)
delta_t=y-x

secs=delta_t.seconds+1

def hello_world():
    print "hello world"
    #...

t = Timer(secs, hello_world)
t.start()

这将在第二天凌晨 1 点执行一个函数(例如 hello_world)。

编辑:

正如@PaulMag 所建议的,更一般地,为了检测是否由于到达月底而必须重新设置月份中的某天,在此上下文中 y 的定义应如下:

y = x.replace(day=x.day, hour=1, minute=0, second=0, microsecond=0) + timedelta(days=1)

使用此修复程序,还需要将 timedelta 添加到导入中。其他代码行保持不变。因此,使用 total_seconds() 函数的完整解决方案是:

from datetime import datetime, timedelta
from threading import Timer

x=datetime.today()
y = x.replace(day=x.day, hour=1, minute=0, second=0, microsecond=0) + timedelta(days=1)
delta_t=y-x

secs=delta_t.total_seconds()

def hello_world():
    print "hello world"
    #...

t = Timer(secs, hello_world)
t.start()

【讨论】:

我需要每天早上这样做...... 回调可以在第一次调用时启动另一个Timer 修正日期逻辑:x = datetime.today() y = (x + timedelta(days=1)).replace(hour=2, minute=0, second=0) delta_t = y - x 不错的解决方案。只是一个问题,你为什么在secs = delta_t.seconds+1的行上加1秒? @Sandi 好问题!这是因为使用 x=datetime.today(),x 可以有 0-999999 微秒(除了其他值);然后,使用 x-y 的秒数将给出一个结果,该结果将在假定日期之前 0-999999 微秒开始; +1 函数将在假定日期之后的 0-999999 微秒处开始。它类似于秒的 ceil() 舍入。但是,如果需要更高的精度,可以将“1”更改为“0.000001*delta_t.microseconds”。【参考方案3】:

APScheduler 可能就是您所追求的。

from datetime import date
from apscheduler.scheduler import Scheduler

# Start the scheduler
sched = Scheduler()
sched.start()

# Define the function that is to be executed
def my_job(text):
    print text

# The job will be executed on November 6th, 2009
exec_date = date(2009, 11, 6)

# Store the job in a variable in case we want to cancel it
job = sched.add_date_job(my_job, exec_date, ['text'])

# The job will be executed on November 6th, 2009 at 16:30:05
job = sched.add_date_job(my_job, datetime(2009, 11, 6, 16, 30, 5), ['text'])

https://apscheduler.readthedocs.io/en/latest/

您可以通过将其构建到您正在安排的功能中来安排另一次运行。

【讨论】:

这不适用于第 3 版的 apscheduler。有谁知道当前语法的类似示例,我遇到问题***.com/q/30280203/2327821 链接失效了 不适用于 python 3 现在为 python 3 工作。【参考方案4】:

我需要类似的东西来完成一项任务。这是我写的代码: 它计算第二天并将时间更改为所需的时间,并找到 currentTime 和下一个计划时间之间的秒数。

import datetime as dt

def my_job():
    print "hello world"
nextDay = dt.datetime.now() + dt.timedelta(days=1)
dateString = nextDay.strftime('%d-%m-%Y') + " 01-00-00"
newDate = nextDay.strptime(dateString,'%d-%m-%Y %H-%M-%S')
delay = (newDate - dt.datetime.now()).total_seconds()
Timer(delay,my_job,()).start()

【讨论】:

嗨,我知道你找到了明天和今天之间的秒数,但是你能解释一下你把它放在'Timer()'中的部分吗?这条线的参数是什么意思,() .我找了 Timer 发现了这个:pypi.org/project/timer3 你需要为此安装 timer3 吗?谢谢! 嗨,你不需要 timer3 库。我从线程中使用了 Timer。 here is the reference。第三个参数是将参数传递给您的函数,即您希望 Timer 在调用时发送给您的函数的参数。 Here 是 Timer 库使用的另一个参考

以上是关于Python脚本每天在同一时间做某事[重复]的主要内容,如果未能解决你的问题,请参考以下文章

跳过一个通知,每天重复

如果元素隐藏则做某事[重复]

如何使用 Timer 类调用方法,做某事,重置计时器,重复?

QPickPointEvent 当鼠标光标在 Python Qt 3D 中的点上方做某事时?

如何只对python循环中的第一项做某事?

python,将Json写入文件[重复]