正如您在下面看到的,我的脚本是我创建的副本,有人可以帮助我改进/修复我的currenttime
任务。
基本上,在白天定期调用测试每3分钟+60秒,每个周期性循环,它应该执行以下任务:
在23:50:00到01:30:00的任何地方,只是闲着,除了检查时间外什么都不做。
from datetime import date, timedelta
from sched import scheduler
from time import time, sleep, strftime
import random
clearscreen = 0
def periodically(runtime, intsmall, intlarge, function):
global clearscreen
## Get current time
currenttime = strftime('%H:%M:%S')
## while currenttime is anywhere between 23:40 and 23:50 then...
while currenttime > '23:30:00' and currenttime < '23:40:00':
## Update time
currenttime = strftime('%H:%M:%S')
print ("""23:30:00 to 23:40:00 | %s""" % (currenttime))
sleep(1)
## If clearscreen = false then...
if clearscreen == False:
## Set clearscreen to true to enable the next part work and to disable this part until the next day.
clearscreen = True
print "changed to true"
## If currenttime is anywhere between 23:50 and 23:59 then...
while currenttime > '23:40:00' and currenttime < '23:50:00':
## Update time
currenttime = strftime('%H:%M:%S')
print ("""23:40:00 to 23:50:00 | %s""" % (currenttime))
sleep(1)
if clearscreen == True:
## clear stuff here
print "cleared"
## Change clearscreen to to stop it running
clearscreen = False
print "changed to false"
## Only allow run_periodically during 01:30 and 23:30
if clearscreen == False:
while currenttime > '23:50:00' and currenttime < '23:59:59':
## Update time
currenttime = strftime('%H:%M:%S')
print ("""23:50:00 to 23:59:59 | %s""" % (currenttime))
sleep(1)
while currenttime > '00:00:00' and currenttime < '01:30:00':
## Update time
currenttime = strftime('%H:%M:%S')
print ("""00:00:00 to 01:30:00 | %s""" % (currenttime))
sleep(1)
runtime += random.randrange(intsmall, intlarge)
s.enter(runtime, 1, function, ())
s.run()
def test():
print "test function"
while True:
periodically(180, -60, +60, test)
非常感谢任何帮助。
关于循环,这是函数应该做的事情:
23:3x:xx - While loop initiated as currenttime fits the while loop's conditions (time is inbetween 23:30:00 and 23:40:00)
23:3x:xx - clearscreen is false, setting it to true.
23:3x:xx to 23:40:00 - currenttime is updated every 1 second(s)
23:40:01 - While loop ended as currenttime no longer fits the while loop's conditions (time is outside of 23:30:00 and 23:40:00)
23:40:01 - While loop initiated as currenttime fits the while loop's conditions (time is inbetween 23:40:00 and 23:50:00)
23:40:01 - clearscreen is true, doing some stuff and then changing clearscreen to false
23:40:01 to 23:50:00 - currenttime is updated every 1 second(s)
23:50:01 - While loop ended as currenttime no longer fits the while loop's conditions (time is outside of 23:40:00 and 23:50:00)
23:50:01 - While loop initiated as currenttime fits the while loop's conditions (time is inbetween 23:50:00 and 23:59:59)
23:50:01 to 23:59:59 - currenttime is updated every 1 second(s)
00:00:00 - While loop ended as currenttime no longer fits the while loop's conditions (time is outside of 23:50:00 and 23:59:59)
00:00:00 - While loop initiated as currenttime fits the while loop's conditions (time is inbetween 00:00:00 and 01:30:00)
00:00:00 and 01:30:00 - currenttime is updated every 1 second(s)
00:00:00 - While loop ended as currenttime no longer fits the while loop's conditions (time is outside of 00:00:00 and 01:30:00)
你提到我反复更新当前时间,然后打印,然后睡觉。我该如何解决这个“问题”?
关于global clearscreen
我不确定你的意思; “你没有锁定它”
我正在运行Windows所以signal.setitemer是不行的,我还需要将某些值/变量存储在我的脚本的内存中,这样Windows上的预定任务就不合适了吗?
你使用sched
模块构建了一个代码示例,但它不起作用,我无法弄清楚如何让它工作,而且它对我来说也相当混乱。我还在学习,而且相当混乱。
答案 0 :(得分:3)
Python无法“忽略while循环”(除非你有一些其他条件)。但是如果while循环告诉Python循环0次,它就会完全正确。
首先,你有这个循环:
while currenttime > '23:30:00' and currenttime < '23:40:00':
......接着是这一个:
while currenttime > '23:40:00' and currenttime < '23:50:00':
想一想23:40:00会发生什么。它既不是在23:40之前也不是在23:40之后,所以在你进入它之前你将跳过第二个循环。
虽然我们正在讨论这些问题,但有两条注意事项:
'23:40:00' < currenttime < '23:50:00'
。datetime
或time
个对象代替字符串来比较时间。接下来,您反复执行此操作:
currenttime = strftime('%H:%M:%S')
print ("""23:40:00 to 23:50:00 | %s""" % (currenttime))
sleep(1)
这意味着currenttime
实际上不是当前时间。通常是一秒钟之前。想想这对你边缘的循环条件有什么影响。
作为旁注,sleep(1)
不能保证只睡一秒钟。如果您的计算机很忙,或者决定它想要进入低功耗模式,它可能会显着超过一秒钟。如果中断飞行,它可能会短于一秒钟。即使在最好的情况下,它通常会在一个方向或另一个方向上关闭半个时钟。所以,如果你需要这个能够正好发射600次,那么通常不会这样做。
与此同时,你有这个:
global clearscreen
显然,任何人都无法在当前代码中更改此内容,因此可能在您的实际代码中,您试图从另一个线程更改它。但你没有锁定它。因此,您很可能不会立即看到更改,甚至永远。
编写调度程序比看起来要困难得多。这就是为什么你通常更好地使用现有的。选项包括:
sched
模块。threading.Timer
。signal.setitemer
。仅适用于具有真实信号的平台(意味着不是Windows),如果您使用线程或fork
,则可能在某些平台上不适用。 Timer
(例如,使用带有即将到来的作业队列的单个计时器线程,而不是每个作业的线程)。由于您特别询问了sched
......有两种方法:
enterabs
以填写当天的任务,再加上明天午夜运行的另一项任务,并做同样的事情。这是第一个看起来的样子:
import sched
import datetime
import time
s = sched.scheduler(time.time, time.sleep)
def dotoday():
now = datetime.date.now()
stime = now.time()
# Schedule "first" every 3 minutes from 22:00 to 22:57
if stime < datetime.time(22, 0):
stime = datetime.time(22, 0)
while stime <= datetime.time(22, 57):
s.enterabs(stime, 1, first, ())
stime += datetime.timedelta(0, 180)
# Schedule "second" every 3 minutes from 23:00 to 23:57
stime = datetime.time(23, 0)
while stime <= datetime.time(23, 57):
s.enterabs(stime, 1, second, ())
stime += datetime.timedelta(0, 180)
# Schedule "dotoday" to run tomorrow
midnight = now.replace(hour=0, minute=0, second=0)
tomorrow = midnight + datetime.timedelta(1, 0)
s.enterabs(tomorrow, 1, dotoday, ())
dotoday()
s.run()
我使这个变得比必要的复杂一点,所以你可以在23:31:17开始它,它将在23:31:17,23:34:17等运行第一批任务等到23:33:00,23:36:00等等。