Выполнять фрагмент кода в час / в дата, определенный в рукописном шрифте в выполнении

В моей программе (Python 3.5) я хочу выполнить функцию в определенный час независимо от, в котором фаза кода была. Но я не знаю никакого решения, которое проверяло бы все время (даже в течение программы), что час, и если состоит, например, 13:15 в том, чтобы выполнять их эта функция. Один while он не служил бы, потому что он всегда выполнял бы цикл, но не скроллировал программу. Какое-то решение?

Мой SO Windows 7 Ultimate.

3
задан 20.06.2017, 18:37
1 ответ

Возможное решение состоит в том, чтобы осуществлять трэд, чтобы выполнять temporizador, и что выполнил функцию, когда будет выполнено условие. Таким образом, главный трэд может продолжать быть функционировавшим без проблем.

Я оставляю тебе пример осуществления. У кода есть комментарии, чтобы доводить до сведения, что оно делается, и пример использования.

#!/usr/bin/env python
# -*- coding: latin-1 -*-

from datetime import datetime, timedelta
from threading import Thread
from time import sleep

class Temporizador(Thread):
    def __init__(self, hora, delay, funcion):
        # El constructor recibe como parámetros:
        ## hora = en un string con formato hh:mm:ss y es la hora a la que queremos que se ejecute la función.
        ## delay = tiempo de espera entre comprobaciones en segundos.
        ## funcion = función a ejecutar.

        super(Temporizador, self).__init__()
        self._estado = True
        self.hora = hora
        self.delay = delay
        self.funcion = funcion

    def stop(self):
        self._estado = False

    def run(self):
        # Pasamos el string a dato tipo datetime
        aux = datetime.strptime(self.hora, '%H:%M:%S')
        # Obtenemos la fecha y hora actuales.
        hora = datetime.now()
        # Sustituimos la hora por la hora a ejecutar la función.
        hora = hora.replace(hour = aux.hour, minute=aux.minute, second=aux.second, microsecond = 0)
        # Comprobamos si la hora ya a pasado o no, si ha pasado sumamos un dia (hoy ya no se ejecutará).
        if hora <= datetime.now():
            hora += timedelta(days=1)
        print('Ejecución automática iniciada')
        print('Proxima ejecución programada el {0} a las {1}'.format(hora.date(),  hora.time()))

        # Iniciamos el ciclo:
        while self._estado:
            # Comparamos la hora actual con la de ejecución y ejecutamos o no la función.
            ## Si se ejecuta sumamos un dia a la fecha objetivo.
            if hora <= datetime.now():
                self.funcion()
                print('Ejecución programada ejecutada el {0} a las {1}'.format(hora.date(),  hora.time()))
                hora += timedelta(days=1)
                print('Próxima ejecución programada el {0} a las {1}'.format(hora.date(),  hora.time()))

            # Esperamos x segundos para volver a ejecutar la comprobación.
            sleep(self.delay)

        #Si usamos el método stop() salimos del ciclo y el hilo terminará.
        else:
             print('Ejecución automática finalizada')


#=========================================================================================
#Ejemplo de uso:

def ejecutar():
    print('Función ejecutada desde hilo')

t = Temporizador('20:42:00',1,ejecutar)# Instanciamos nuestra clase Temporizador
t.start() #Iniciamos el hilo

#Mientras el programa principal puede seguir funcinando:
sleep(2)
for _ in range(10):
    print('Imprimiendo desde hilo principal')
    sleep(2)

# Si en cualquier momento queremos detener el hilo desde la aplicacion simplemete usamos el método stop()
sleep(120) # Simulamos un tiempo de espera durante el cual el programa principal puede seguir funcionando. 
t.stop()   # Detenemos el hilo.

Вывод кода доказательства:

Автоматическое инициализировавшее выполнение
Предстоящее запрограммированное выполнение 2016-12-08 в 20:36:00
Печатая с главного трэда
Печатая с главного трэда
Печатая с главного трэда
Печатая с главного трэда
Печатая с главного трэда
Печатая с главного трэда
Печатая с главного трэда
Печатая с главного трэда
Печатая с главного трэда
Печатая с главного трэда
Функция, выполненная с трэда
Запрограммированное выполненное выполнение 2016-12-08 в 20:36:00
Предстоящее запрограммированное выполнение 2016-12-09 в 20:36:00
Автоматическое законченное выполнение

Ввиду того, что у кода есть столько комментариев и нормативных объемов производства, я оставляю 'чистую' версию того, который только включает класс Temporizador и без информации из-за консоли прогресса:

#!/usr/bin/env python
# -*- coding: latin-1 -*-

from datetime import datetime, timedelta
from threading import Thread
from time import sleep

class Temporizador(Thread):
    def __init__(self, hora, delay, funcion):
        super(Temporizador, self).__init__()
        self._estado = True
        self.hora = hora
        self.delay = delay
        self.funcion = funcion

    def stop(self):
        self._estado = False

    def run(self):
        aux = datetime.strptime(self.hora, '%H:%M:%S')
        hora = datetime.now()
        hora = hora.replace(hour = aux.hour, minute=aux.minute, second=aux.second, microsecond = 0)
        if hora <= datetime.now():
            hora += timedelta(days=1)

        while self._estado:
            if hora <= datetime.now():
                self.funcion()
                hora += timedelta(days=1)
            sleep(self.delay)

Пока он был активным трэд выполнит функцию в каждый день в этот час до тех пор, пока он не задержится используя метод stop(). Когда ты захочешь закончить программу, используй этот метод раньше гарантировать для тебя, что трэд заканчивается правильно.

Все модули принадлежат стандартной библиотеке Python (datetime, я украл, threading) и код функционирует без изменений в Python 2.7 также.

Если ты нуждаешься в том, чтобы иметь информацию, между которым он обрабатывается в приспособленном трэде и твоей главной программе, используй какой-то метод, уверенный в коммуникации между трэдами, как очередь (Queue).

6
ответ дан 24.11.2019, 12:13
  • 1
    Это превосходный ответ! Особенно ссылка на возможное осуществление как останавливать thread; вышеупомянутое будучи единственной ссылкой в SOes. – Kenny Barrera 28.09.2017, 00:21