[Python] come ripeto una funzione dopo un certo intervallo di tempo?

Y3s y3s a katamail.com
Lun 16 Lug 2007 00:22:42 CEST


Il giorno 15/lug/07, alle ore 23:38, allanon ha scritto:

> Sun 15 July 2007, alle 16:47 +0200, Eriol ha scritto:
>> On Friday 13 July 2007, allanon wrote:
>>> come potrei fare?
>>
>> Importare dal modulo threading:
>>
>> from threading import Timer
>>
>
> ti ringrazio per la dritta,
> infatti ho altre due domande per te :)
>

Rispondo io, va bene lo stesso? ;-)

> 1) come diavolo fai a saperlo dato che nella pagine online di  
> reference
> non c'e' scritto :p
>

Sa leggere la documentazione ;-)

http://www.python.org/doc/current/lib/module-threading.html

> 2)
>
> questa e' la parte incriminata del mio codice
>
> if __name__ == '__main__':
> # creo l'oggetto database
>    db = MySQLdb.connect(host = HOST,
>       user = USER,
>       passwd = PASSWD,
>       db=DATABASE
>       )
>    c=db.cursor() # crea il cursore
>    t = Timer(5.0, Repeated_Function(c))
>    t.start()
>
>
> lancio lo script,
> viene eseguita la Repeated_Function per 1 volta
> dopo 5 secondi ottengo questo errore
>
> Traceback (most recent call last):
>   File "threading.py", line 442, in __bootstrap
>     self.run()
>   File "threading.py", line 607, in run
>     self.function(*self.args, **self.kwargs)
> TypeError: 'NoneType' object is not callable
>
>
> la connessione al db dovrebbe essere sempre attiva giusto?
> e lo stesso dovrebbe valere per il cursore,
> non capisco cosa non funziona O_O
>

Stai passando al timer il valore di ritorno della *chiamata* alla  
funzione. In questo modo, la funzione Repeated_Function viene  
chiamata subito, e al timer viene passato il suo valore di ritorno  
(nel tuo caso l'oggetto None). Questo ti spiega il messaggio d'errore.
La riga giusta dovrebbe essere qualcosa di simile (passi il nome  
della funzione e una sequenza dei suoi parametri):

t = Timer(5.0, Repeated_Function, (c,))

Tieni presente che comunque il timer è one-shot, ovvero se vuoi che  
venga eseguita *ogni 5 secondi* devi ri-schedulare (che brutto  
termine!) l'azione dopo che è stata eseguita. Questo se ti serve che  
il tuo programma continui a funzionare durante i 5 secondi di attesa,  
in caso contrario la cosa più semplice è quella di seguito.

> il mio intento e' quello di lasciare sempre aperta una connessione
> e di rinnovare solo la query ogni tot secondi
>

In tal caso (ovvero se devi solo eseguire la query ogni 5 secondi,  
senza fare niente nel frattempo), il codice più corretto dovrebbe  
essere qualcosa tipo:

import time

while True:
     # Esegue la query o qualunque cosa
     ...
     time.sleep(5)	# Attende 5 secondi

Oppure usare il modulo sched, che è fatto proprio per questo genere  
di cose.

Nel caso in cui l'esecuzione del tuo programma deve proseguire  
durante l'attesa, puoi anche provare a dare un'occhiata a Twisted,  
che per queste cose ti da molta potenza "a basso costo" (è piuttosto  
semplice in casi del genere)

--
Antonio Valente




Maggiori informazioni sulla lista Python