Ожидание выполнения функции в 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.
Другие вопросы по тегам