====== Décorateur pour rendre une fonctionne asynchrone ====== Source : https://pykodz.wordpress.com/2010/11/15/async-decorator/ #!/usr/bin/env python # -*- coding: utf-8 -*- from threading import Thread from time import sleep class async(Thread): def __init__(self, callback, errback): super(async, self).__init__() self.callback = callback self.errback = errback def __call__(self, func): # à l'appel de la fonction, on récupère juste la fonction # et ses arguments, et on lance notre thread def wrapper(*args, **kwargs): self.func = func self.args = args self.kwargs = kwargs self.start() return wrapper def run(self): try: retval = self.func(*self.args, **self.kwargs) self.callback(retval) except Exception as err: self.errback(err) def my_callback(retval): print "CALLBACK:", retval # ici on peut faire des opérations supplémentaires # sur la valeur renvoyée par la fonction. # ce code est appelé par le thread, il ne peut donc # pas bloquer notre thread principal def my_errback(err): print "ERRBACK", err # ici on peut re-lancer l'exception, ou simplement # l'ignorer. Ce code est également appelé dans le thread @async(my_callback, my_errback) def ma_fonction_reussie(n): sleep(n) return n @async(my_callback, my_errback) def ma_fonction_foireuse(n): sleep(n) raise AttributeError("Got %s, expected 'foo'" % n) ma_fonction_reussie(5) ma_fonction_foireuse(7) # histoire de passer le temps pendant ce temps là... for i in range(10): print "MAIN:", i sleep(1) * Résultat: 1 2 3 4 5 6 7 8 9 10 11 12 MAIN: 0 MAIN: 1 MAIN: 2 MAIN: 3 MAIN: 4 MAIN: 5 CALLBACK: 5 MAIN: 6 MAIN: 7 ERRBACK: Got 7, expected 'foo' MAIN: 8 MAIN: 9