[英]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
我不确定是否有支持两个计划中任何一个的现有方法。 我知道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并看看会发生什么。
我知道我们可以使用subprocess.run(..., check=True)
运行子subprocess.run(..., check=True)
来获取subprocess.SubprocessError
,但是由于子流程可以是任何东西(不仅是python流程),因此我们实际上无法拦截实际的发生的异常。
将python文件作为模块加载到此文件的一个问题是,我们无法提供必要的参数,除非我们能够以某种方式欺骗从底层脚本运行的sys.argv[]
或argparse
。 if __name__ == "__main__":
可能具有的脚本也不会执行,除非我们也欺骗了它。
有任何想法吗?
我更喜欢方法2。 尽可能避免使用subprocess
或system
从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.