我正在代码中调用一个第三方python库,该库在响应异常条件时只是exit
s,而不是raise
ing异常。我认为exit
本身不是来自python本身,而是来自一个链接的C文件。在linux上使用strace
无疑表明它正在调用exit。
不幸的是,这导致我的整个程序退出。我想要的是能够捕捉到这个";退出";事件并引发异常,然后让我的处理代码对参数进行一些更改并再次调用。我正在寻找捕获退出事件的方法,到目前为止,我已经看到了atexit
,它实际上似乎不允许您继续执行,而且我还可以将子流程中的调用与退出事件隔离开来,以保护自己的防火墙。对我来说,这似乎是一个太不雅的解决方案,所以我想知道是否还有其他人可以参与进来。
在这一点上,我还没有尝试任何具体的方法,我只是在寻找这个问题的可能解决方案。
正如上面的注释中所指出的,如果不创建子流程,就没有真正的方法可以做到这一点。最后,我使用pythonmultiprocessing
库来解决这个问题。解决方案看起来像:
import multiprocessing as mp
import unsafe_module # my external dependency that hard exits unexpectedly
def access_unsafe_module_safely(unsafe_args, pipe):
unsafe_obj = unsafe_module.UnsafeClass()
# the next line causes the process to exit when certain args are passed
results = unsafe_obj.do_unsafe_thing(unsafe_args)
# report the results using multiprocessing.Pipe
pipe.send(results)
# unsafe_args are passed in from the user
def main(unsafe_args):
(receive_end, send_end) = mp.Pipe(False) # False gives non-duplex mode
# the target callable is invoked with args, which must be iterable
process = mp.Process(target=access_unsafe_module_safely, args=(unsafe_args, send_end))
process.start()
process.join() # waits until the subprocess is complete
# if you know your module's exit codes, you can be smarter here
if process.exitcode != 0: # generally signals error
raise RuntimeError("something bad happened in unsafe_module")
# gets the returned results from the subprocess
results = receive_end.recv()
# (Python 3.7+) cleans up the subprocess resources
process.close()
# continue on with results from here...
不幸的是,找图书馆维护人员没有多大意义;它是用于科学C/C++应用程序的Python绑定。exit
对他们的设计案例来说非常有意义。