Ожидание выполнения функции в Python 3 с использованием datetimenow?
Я возиться с datetimenow()
и мне интересно, как бы вы пошли о "планировании" выполнения функции, когда есть 2 даты (сейчас и в будущем)?
По сути, я хочу, чтобы программирование продолжалось, когда дата (и время) не совпадают, но когда это так, вызовите некоторую функцию.
Я имею в виду:
from time import sleep
import time
import datetime
timenow = datetime.datetime.now()
future = datetime.datetime(2018, 8, 19, 15,28)
while timenow != future:
sleep(1.0)
if timenow == future:
'''calling some function'''
Результат:
Запуск этого кода, кажется, только продолжает цикл, хотя минуты, указанные в future
равны минутам timenow
,
2 ответа
У вас есть две отдельные проблемы здесь, и вам нужно исправить обе.
Первая проблема заключается в том, что вы никогда не обновляете timenow
в вашей петле. Независимо от того, сколько времени было, когда ваша программа началась, это ценность timenow
навсегда.
Чтобы это исправить, вам нужно обновлять его каждый раз через цикл:
while timenow != future:
sleep(1.0)
timenow = datetime.datetime.now()
Вторая проблема заключается в том, что если now
это, скажем, 2018-08-19 15:27:59.123456
, это не равно 2018-08-19 15:28:00.000000
, И через секунду, 2018-08-19 15:28:00.131313
также не равно 2018-08-19 15:28:00.000000
, Вероятность попадания в микросекунду составляет примерно 1 к миллиону, когда вы проверяете только раз в секунду.
Чтобы это исправить, просто используйте <
вместо !=
:
while timenow < future:
sleep(1.0)
timenow = datetime.datetime.now()
Сейчас, 2018-08-19 15:27:59.123456
меньше времени, которое вы ждете, но 2018-08-19 15:28:00.131313
не является. Итак, вы не пропустите это.
Пока мы на этом:
Там нет необходимости в этом if
заявление на всех. Вы просто тестируете противоположность while
состояние. Но единственный способ добраться сюда - это while
условие ложно, поэтому противоположное условие всегда будет истинным, так зачем его проверять?
Кроме того, если единственное, что вы используете timenow
for находится в этой проверке, вам даже не нужно вставлять его в переменную; просто позвони now()
непосредственно.
Так:
from time import sleep
import datetime
future = datetime.datetime(2018, 8, 19, 15,28)
while datetime.datetime.now() < future:
sleep(1.0)
'''calling some function'''
Между тем, на самом деле нет причин спать на секунду. Почему бы просто не спать один раз, пока future
? В некоторых версиях Python sleep
может вернуться рано, так что вам все еще нужно while
цикл, но вы все еще можете сделать это:
from time import sleep
import datetime
future = datetime.datetime(2018, 8, 19, 15,28)
while datetime.datetime.now() < future:
sleep((future - datetime.datetime.now()).total_seconds())
'''calling some function'''
В большинстве случаев он будет спать ровно один раз, иногда, может быть, два или три раза, а не снова и снова, так что, скажем, он не остановит ваш ноутбук от перехода в режим пониженного энергопотребления.
Кроме того, гораздо меньше шансов, что он проснется, скажем, 2018-08-19 15:28:00.987654
вместо (очень близко) на втором. Это может не иметь значения для вашего использования, но если это имеет значение, то пробуждение на втором, безусловно, то, что вам нужно.
Что вам нужно будет сделать, это указать, насколько точно вы хотите, чтобы это равенство было. Для этого вы укажете интервал времени, который приемлемо считается равным. Посмотрите это ТАК сообщение на примере того, как это сделать. Вы получите что-то такое же прямое, как
if min_future_time < timenow and timenow < max_future_time:
# Do something.