2009-10-29 4 views
13

J'utilise Python 2.5 et j'essaie d'utiliser un excepthook auto-défini dans mon programme. Dans le fil principal cela fonctionne parfaitement bien. Mais dans un fil commencé avec le module de filetage, le excepthook habituel est appelé.'sys.excepthook' et le filetage

Voici un exemple montrant le problème. Décommenter le commentaire montre le comportement souhaité.

import threading, sys 

def myexcepthook(type, value, tb): 
    print 'myexcepthook' 

class A(threading.Thread, object): 

    def __init__(self): 
     threading.Thread.__init__(self, verbose=True) 
#  raise Exception('in main') 
     self.start() 

    def run(self): 
     print 'A' 
     raise Exception('in thread')    

if __name__ == "__main__": 
    sys.excepthook = myexcepthook 
    A() 

Alors, comment puis-je utiliser mon propre excepthook dans un fil?

Répondre

9

Il semble qu'il y ait un bug connexe rapporté here avec des solutions de contournement. Les hacks suggérés fonctionnent dans un try/catch, puis appellent

+1

Merci - la troisième solution de contournement fonctionne parfaitement! – Sebastian

8

Il semble que ce bogue soit toujours présent dans (au moins) 3.4, et l'une des solutions de contournement dans la discussion liée à Nadia Alramli semble fonctionner dans Python 3.4 aussi. Pour des raisons de commodité et de documentation, je vais poster le code pour (à mon avis) la meilleure solution de contournement ici. J'ai mis à jour le style de codage et les commentaires légèrement pour le rendre plus PEP8 et Pythonic.

import sys 
import threading 

def setup_thread_excepthook(): 
    """ 
    Workaround for `sys.excepthook` thread bug from: 
    http://bugs.python.org/issue1230540 

    Call once from the main thread before creating any threads. 
    """ 

    init_original = threading.Thread.__init__ 

    def init(self, *args, **kwargs): 

     init_original(self, *args, **kwargs) 
     run_original = self.run 

     def run_with_except_hook(*args2, **kwargs2): 
      try: 
       run_original(*args2, **kwargs2) 
      except Exception: 
       sys.excepthook(*sys.exc_info()) 

     self.run = run_with_except_hook 

    threading.Thread.__init__ = init