![](/img/trans.png)
[英]Python subprocess module: Catch exception from a child process in parent process
[英]Catch an exception raised by a child process in a parent process
我正在嘗試捕獲由子進程引發的異常,並且遇到了一些問題。 我的代碼的要點是:
class CustomException(Exception):
def __init__(self, msg):
self.msg = msg
def __str__(self):
return self.msg
def update(partition):
if os.getpid() % 2 == 0:
raise CustomException('PID was divisible by 2!')
else:
# Do something fancy
if __name__ == '__main__':
try:
some_response = get_response_from_another_method()
partition_size = 100
p = Pool(config.NUMBER_OF_PROCESSES)
for i in range(0, NUMBER_OF_PROCESSES):
partition = get_partition(some_response, partition_size)
x = p.apply_async(update, args=(partition,))
x.get()
p.close()
p.join()
except CustomException as e:
log.error('There was an error')
if email_notifier.send_notification(e.msg):
log.debug('Email notification sent')
else:
log.error('An error occurred while sending an email.')
當我跑這個時,我看到:
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 484, in run
self.__target(*self.__args, **self.__kwargs)
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/multiprocessing/pool.py", line 259, in _handle_results
task = get()
TypeError: ('__init__() takes exactly 2 arguments (1 given)', <class 'CustomException'>, ())
有這樣的設施嗎? 謝謝!!
簡而言之,這在Python 2中是一個怪癖,並且在此錯誤報告中引用了相關問題。 它與如何腌制異常有關。 最簡單的解決方案可能是更改CustomException
以便調用其父類初始化程序。 或者,如果你能夠,我建議你轉向Python 3。
例如,此代碼在Python 2和Python 3中都可以正常工作:
from multiprocessing import Pool
class CustomException(Exception):
pass
def foo():
raise CustomException('PID was divisible by 2!')
pool = Pool()
result = pool.apply_async(foo, [])
但是如果我們改變CustomException
以便它有一個必需的參數:
class CustomException(Exception):
def __init__(self, required):
self.required = required
上面的示例導致在Python 2下TypeError
。它在Python 3下運行。
問題是CustomException
繼承了Exception
的__reduce__
方法,該方法告訴Python如何__reduce__
實例。 繼承的__reduce__
對CustomException
的調用簽名一無所知,因此unpickling沒有正確完成。
快速解決方法是簡單地調用父類的__init__
:
class CustomException(Exception):
def __init__(self, msg):
super(Exception, self).__init__()
self.msg = msg
但是既然你真的沒有對這條消息做任何特別的事情,為什么不定義:
class CustomException(Exception):
pass
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.