2017-10-16 10 views
2

J'essaie d'apprendre le module de signal de python. S'il vous plaît considérer l'exemple ci-dessous:Le module de signal ne lève pas l'exception

def timeoutFn(func, args=(), kwargs={}, timeout_duration=1, default=None): 
    import signal 

    class TimeoutError(Exception): 
     pass 

    def handler(signum, frame): 
     print "Trying to raise exception" 
     raise TimeoutError 

    # set the timeout handler 
    signal.signal(signal.SIGALRM, handler) 
    signal.alarm(timeout_duration) 
    try: 
     result = func(*args, **kwargs) 
    except TimeoutError as exc: 
     result = default 
    finally: 
     signal.alarm(0) 

    return result 

et,

import time 

def foo(): 
    for i in range(10): 
     time.sleep(0.5) 
     print "Sleeping" 

En appelant la fonction timeoutFn(foo) ce qui suit est imprimé, mais il soulève l'exception.

Ne devrait-il pas déclencher l'erreur TimeoutError? Mais, tout ce qu'il imprime est

Sleeping Trying to raise exception et les arrêts du programme.

+0

Cela fonctionne correctement. Qu'attendez-vous? Cette exception a été soulevée? – Trilliput

+0

Après l'impression "Essayer de lever l'exception", je n'obtiens aucun TimeoutError – Aditya

Répondre

0

L'exception n'a pas été déclenchée, car vous l'avez interceptée. Faites attention à la ligne:

except TimeoutError as exc: 
    result = default 

Les moyens de bloc, que si le TimeoutError d'exception a été soulevée, result sera affecté à default (qui est None dans votre exemple) et les scripts se poursuit encore sans montrer une exception.

Mise à jour:

signal.alarm ne pas arrêter le flux. L'exception sera donc déclenchée par timeout et si le script sera à ce moment-là dans un bloc try, l'exception sera interceptée. Vous pouvez voir mieux comment cela fonctionne si vous augmentez timeout_duration à 3. Puis, il y aura plus de temps pour imprimer plusieurs messages 'sommeil'. Cela montre qu'au moment où l'exception est levée, l'interprète était entré dans le bloc try.

+0

Cette ligne intercepte l'exception qui se produit dans le bloc "try", pas l'exception qui se produit avant l'essai. 'Signal.alarm' n'arrête pas le flux. – Aditya

+0

L'exception sera donc déclenchée par timeout et si le script se trouve dans un bloc try, l'exception sera interceptée. Vous pouvez voir mieux comment cela fonctionne si vous augmentez timeout_duration à 3. Puis, il y aura plus de temps pour imprimer plusieurs messages 'sleep'. – Trilliput