簡體   English   中英

捕獲父進程中子進程引發的異常

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM