from threading import Thread
import traceback
class PropagatingThread(Thread):
def run(self):
self.exc = None
try:
if hasattr(self, '_Thread__target'):
# Thread uses name mangling prior to Python 3.
self.ret = self._Thread__target(*self._Thread__args, **self._Thread__kwargs)
else:
self.ret = self._target(*self._args, **self._kwargs)
except BaseException as e:
self.exc = e
finally:
if hasattr(self, '_Thread__target'):
del self._Thread__target, self._Thread__args, self._Thread__kwargs
else:
del self._target, self._args, self._kwargs
def join(self):
super(PropagatingThread, self).join()
if self.exc:
raise self.exc
return self.ret
def f(*args, **kwargs):
print(args)
print(kwargs)
raise Exception('I suck')
if __name__ == "__main__":
thread_list = []
try:
thread_list.append(PropagatingThread(target=f, args=(5,), kwargs={'hello': 'world'}))
thread_list.append(PropagatingThread(target=f, args=(5,), kwargs={'hello': 'worlds'}))
for thread in thread_list:
thread.daemon = True
thread.start()
for thread in thread_list:
thread.join()
except BaseException as err:
exe_info = traceback.format_exc()
print(str(exe_info))
结果为:
(5,)
{'hello': 'world'}
(5,)
{'hello': 'worlds'}
Traceback (most recent call last):
File "E:/project/medusa/utils/test.py", line 43, in <module>
thread.join()
File "E:/project/medusa/utils/test.py", line 25, in join
raise self.exc
File "E:/project/medusa/utils/test.py", line 12, in run
self.ret = self._target(*self._args, **self._kwargs)
File "E:/project/medusa/utils/test.py", line 31, in f
raise Exception('I suck')
Exception: I suck
Process finished with exit code 0
其他方法见地址:
https://stackoverflow.com/questions/2829329/catch-a-threads-exception-in-the-caller-thread-in-python