繁体   English   中英

从子流程重构或捕获python错误

[英]Reconstructing or catching python errors from subprocess

我目前正试图从纯stderr或拦截脚本并捕获其Exception来获取python堆栈跟踪和错误的属性。 两种方法都可以。 这可能是XY问题,因此欢迎您选择其他方法。

我目前正在编写一种程序,将参数重定向以调用另一个python脚本:

import sys, subprocess
pyargs = sys.argv[1:] # Suppose pyargs is something like ["a.py", "123"]
result = subprocess.run(["python"] + pyargs, stdout=subprocess.PIPE, 
    stderr=subprocess.PIPE)
error = result.stderr # do something with this

方法1:解析转储

我不确定是否有支持两个计划中任何一个的现有方法。 我知道python错误转储以非常公式化的方式显示:

import sys, traceback
exc_type, exc_value, exc_traceback = sys.exc_info() # shows formatting
traceback.print_exc() # prints the stderr of what we wanted.

所以我想也许我们可以解析stderr并看看会发生什么。

方法2:捕获异常

我知道我们可以使用subprocess.run(..., check=True)运行子subprocess.run(..., check=True)来获取subprocess.SubprocessError ,但是由于子流程可以是任何东西(不仅是python流程),因此我们实际上无法拦截实际的发生的异常。

将python文件作为模块加载到此文件的一个问题是,我们无法提供必要的参数,除非我们能够以某种方式欺骗从底层脚本运行的sys.argv[]argparse if __name__ == "__main__":可能具有的脚本也不会执行,除非我们也欺骗了它。

有任何想法吗?

我更喜欢方法2。 尽可能避免使用subprocesssystem从Python调用Python。

更改sys.argv的值很容易-您只需使用常规分配将其覆盖即可。

欺骗__name__ == "__main__"条件比较困难。 不幸的是,这可能意味着您不能简单地以通常的方式导入模块。 根据如何将模块作为__main__导入? ,您可以使用runpy模块执行模块并提供所需的__name__值。

import runpy
import sys
sys.argv = ["C:/", "foo", "bar"]
try:
    runpy.run_module("yourmodulename", {}, "__main__")
except Exception as e:
    print("caught exception:", e)

现在,您可以捕获模块引发的所有未捕获的异常,并根据需要在except处理它们。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM