¿Cómo crear un disparador con threading.Timer?

Acabo de descubrir Python el mes pasado, no soy un progtwigdor en absoluto. Estoy tratando de crear mi propio software para un instrumento electrónico. Realmente necesito crear un disparador que llame a una función cada 0.04 ms (si es posible). Intenté con esto:

En mi primer archivo Metronome.py:

class Metronome: def __init__(self, clip, _matrix): self.clip = clip self._matrix = _matrix self.inc = -1 def _trigger(self): self.inc = self.inc + 1 self._matrix.get_button(self.inc, 1).send_value(GREEN_FULL) t = threading.Timer(1.0, self._trigger).start() 

En un segundo archivo y una nueva clase:

Importe la función anterior con:

 from Metronome.py import Metronome 

Llamo a la función anterior con:

 Metronome(self.clip, self._matrix)._trigger() 

En la función _trigger , self._matrix.get_button(self.inc, 1).send_value(GREEN_FULL) me permite enviar una retroalimentación de led en la interfaz de mi instrumento. Cuando lanzo el progtwig, recibo la primera retroalimentación en mi instrumento. Sin embargo, los demás tardan más de 1 segundo en configurarse y algunos de ellos aparecen al mismo tiempo. Además, después de cada retroalimentación, aumenta el tiempo de la siguiente (como 5/10 segundo). No lo entiendo

aparte de otras cuestiones sobre cómo se llama la clase de Metronome (ver comentarios arriba), creo que el método de _trigger debería ser más como:

 def _trigger(self): while True: self.inc += 1 self._matrix.get_button(self.inc, 1).send_value(GREEN_FULL) if (whatever_exit_condition): break time.sleep(time_interval_in_seconds) 

Si no hay una condición de salida, simplemente elimine el bloque if .

En pocas palabras: evite crear un nuevo temporizador en cada ciclo. En su lugar, cree un solo temporizador, cuando comience a llamar al método:

 t = threading.Timer(1.0, Metronome(self.clip, self._matrix)._trigger).start() 

Aquí hay un ejemplo práctico de cómo usar el temporizador:

 #! /usr/bin/env python from sys import argv import time import threading def f(): retry = 0 while True: print "f, retry=", retry retry += 1 if retry > 3: break time.sleep(2) print ("f exited") if __name__ == "__main__": if len(argv) <= 1: print "usage: %s num" % (argv[0],) exit(1) t = threading.Timer(1.0, f) t.start() for i in range(int(argv[1])): time.sleep(1) print "main, i=", i 

si lo ejecutas con:

 python timer.py 10 

da salida:

 f, retry= 0 main, i= 0 main, i= 1 f, retry= 1 main, i= 2 main, i= 3 f, retry= 2 main, i= 4 main, i= 5 f, retry= 3 f exited main, i= 6 main, i= 7 main, i= 8 main, i= 9 

Básicamente, el subproceso principal está vivo y hace lo suyo, mientras que el subproceso del temporizador se crea a través del temporizador una vez y sigue haciendo su bit (por ejemplo, señala algo al usuario en su caso), por un número limitado de veces (3), durmiendo entre cada ciclo. Espero que esté más claro ahora.