2010-03-24 8 views
3

J'essaie de me familiariser avec Python, en essayant de remplacer du C par celui-ci. J'ai rencontré un problème avec le partage de données entre les modules, ou plus probablement ma compréhension de l'ensemble. J'ai un module de signal simplifié est:Besoin de comprendre les signaux et les modules Python

import sys, signal 

sigterm_caught = False 

def SignalHandler(signum, stackframe): 
    if signum == signal.SIGTERM: 
    sigterm_caught = True 
    sys.stdout.write("SIGTERM caught\n") 

def SignalSetup(): 
    signal.signal(signal.SIGTERM, SignalHandler) 

et mon code principal a une boucle comme ceci:

signals.SignalSetup() 
while signals.sigterm_caught == False: 
    sys.stdout.write("sigterm_caught=%s\n" % str(signals.sigterm_caught)) 
    time.sleep(5) 

je le lance, puis tuer le processus, à l'intérieur signals.py il obtient le signal , définit sigterm_caught sur True, mais la boucle dans le processus principal ne voit pas de changement de valeur de sigterm_caught.

Donc (a) mon approche est-elle complètement fausse pour la façon Python? (b) est-ce que je fais quelque chose de mal en essayant de référencer des variables dans le module? et (c) devrais-je gérer les signaux différemment, comme lever une exception?

Ajout: Est-il préférable de gérer les signaux en levant une exception ou mon ancienne approche C est-elle toujours valide?

Répondre

7

Vous devez ajouter une déclaration global au gestionnaire:

def SignalHandler(signum, stackframe): 
    global sigterm_caught 
    if signum == signal.SIGTERM: 
    sigterm_caught = True 
    sys.stdout.write("SIGTERM caught\n") 

Le compilateur Python, par défaut, estime chaque nom (comme sigterm_caught) pour être locale à une fonction si elle semble la assign de fonction au nom le rôle de l'instruction global consiste à inverser cette valeur par défaut, de sorte que le compilateur Python considère que le nom est global (c'est-à-dire, un nom supérieur au niveau du module).

+0

qui fonctionne. Merci. Je ferais mieux de relire la portée de Python. – codebunny

+0

Vaut-il mieux gérer les signaux en levant une exception, ou la méthode des variables globales est-elle toujours valide? – codebunny

+1

@codebunny, la seule exception que vous devriez toujours relever de manière "asynchrone" (c'est-à-dire, provenir d'une cause externe non liée au code en cours d'exécution) est 'KeyboardInterrupt'; canaliser tous les signaux à travers cette exception (ou sous-classes de celui-ci) est une possibilité, mais à mon humble avis, lorsque cela est possible, votre alternative est préférable (opinions peuvent différer ;-). –

3

Si vous êtes écriture à une variable globale, l'utilisation mondiale:

sigterm_caught = False 

def SignalHandler(signum, stackframe): 
    global sigterm_caught 
    if signum == signal.SIGTERM: 
    sigterm_caught = True 
    sys.stdout.write("SIGTERM caught\n") 
+0

cela fonctionnera-t-il dans une classe? Je suis incapable d'accéder à la valeur définie à self.variable via le gestionnaire de signal dans d'autres méthodes après avoir donné 'global self.variable' dans __init__. – Vivek

Questions connexes