从子进程中重新引发异常

问题描述 投票:0回答:3

我在应该引发异常的子进程中执行代码。

当从子进程返回异常时(最好同时保留堆栈跟踪),我想在主进程中引发相同的异常,但我不知道该怎么做。

我很好地从子进程中捕获了 stderr,但我找不到如何解析它,所以我得到了异常类型。我将如何做到这一点?

我正在使用 python 2.7

主要方法

import subprocess

example=subprocess.Popen(["python","example.py"],
                                    stdout = subprocess.PIPE,
                                    stderr = subprocess.PIPE)
return_obj, return_error = example.communicate()

if return_error:
# replace with error from subprocess
  print "Should raise ",NameError('HiThere')
  raise TypeError('Wrong type')

子进程

raise NameError('HiThere')
python python-2.7 exception subprocess
3个回答
4
投票

如果你想要的只是在单独的进程中运行你的 python 代码,你可能不应该使用

subprocess
。正如 Serge Ballesta 所说,
subprocess
' 的目的是在操作系统级别运行不同的程序,而不特别关心它是什么 - 没有什么可以帮助您正确处理 python 解释器进程的复杂性。

对于这种目的,最好是简单地

import
您的代码并使用
multiprocessing
,它公开了一个高级接口来帮助您在多个进程中运行python代码。

假设您在

main
上有一个定义明确的
example.py
函数:

from examply import main as example_main
import multiprocessing
pool= multiprocessing.Pool(1)
pool.apply( example_main )

使用此代码,异常和返回值都将透明地提供给您的主进程。

你也可以使用

Pool.apply_async
,如果你不想阻塞等待结果。


1
投票

子进程执行不同的native应用程序。它可以是 java、C++、lisp 甚至 Fortran 或 Cobol。所以你只有两种方法可以从 Python 子进程中获取异常:

  • 完全忘记子进程,直接在同一个python程序中调用python代码,简单
    try except
    就可以完成
  • 在主进程和子进程之间的接口契约中定义,例如,如果没有发生致命异常,则要求错误输出必须为空,否则包含异常的 pickle 和堆栈跟踪。

0
投票

如果两个进程都是python进程,并且必须使用管道,异常对象可以通过管道序列化。

来电者:

parent_conn.send(event)
result = parent_conn.recv()
if isinstance(result, Exception):
    raise result
else:
    return result

接收器:

def subprocess_loop(parent_conn, child_conn):
    
    parent_conn.close()

    while True:
        event = child_conn.recv()
        try:
            result = event_handler(event)
        except Exception as exc:
            child_conn.send(exc)
            continue
        child_conn.send(result)

接收进程创建:

parent_conn, child_conn = Pipe()
process = Process(target=subprocess_loop, args=(parent_conn, child_conn))
process.start()
child_conn.close()
© www.soinside.com 2019 - 2024. All rights reserved.