[英]Reconstructing or catching python errors from subprocess
I'm currently trying to get attributes of a python stack trace and error from either purely the stderr or intercepting a script and catching its Exception. 我目前正试图从纯stderr或拦截脚本并捕获其Exception来获取python堆栈跟踪和错误的属性。 Either way is fine.
两种方法都可以。 This may be an XY problem so alternatives are welcome.
这可能是XY问题,因此欢迎您选择其他方法。
I am currently writing a program that kind of, redirects the arguments to call another python script: 我目前正在编写一种程序,将参数重定向以调用另一个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
I'm not sure whether there is any existing method that supports either of the two plans. 我不确定是否有支持两个计划中任何一个的现有方法。 I know that the python error dump is displayed in a very formulaic way:
我知道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.
And so I thought perhaps we could parse the stderr and see what happens. 所以我想也许我们可以解析stderr并看看会发生什么。
I know that we can run subprocess with subprocess.run(..., check=True)
to get the subprocess.SubprocessError
, but since the subprocess can be anything(not just a python process), we can't actually intercept the actual exception that occurred. 我知道我们可以使用
subprocess.run(..., check=True)
运行子subprocess.run(..., check=True)
来获取subprocess.SubprocessError
,但是由于子流程可以是任何东西(不仅是python流程),因此我们实际上无法拦截实际的发生的异常。
One issue with loading in the python file as a module to this file, is that we cannot supply the necessary arguments, unless we can somehow spoof the sys.argv[]
or argparse
that's running from the underlying script. 将python文件作为模块加载到此文件的一个问题是,我们无法提供必要的参数,除非我们能够以某种方式欺骗从底层脚本运行的
sys.argv[]
或argparse
。 Scripts that may have if __name__ == "__main__":
will not execute either unless we spoof that too. if __name__ == "__main__":
可能具有的脚本也不会执行,除非我们也欺骗了它。
Any ideas? 有任何想法吗?
I prefer approach #2. 我更喜欢方法2。 Whenever possible, I avoid using
subprocess
or system
to call Python from Python. 尽可能避免使用
subprocess
或system
从Python调用Python。
Changing the value of sys.argv
is easy - you just overwrite it using regular assignment. 更改
sys.argv
的值很容易-您只需使用常规分配将其覆盖即可。
Tricking the __name__ == "__main__"
conditional is harder. 欺骗
__name__ == "__main__"
条件比较困难。 Unfortunately, it probably means that you can't simply import the module in the usual way. 不幸的是,这可能意味着您不能简单地以通常的方式导入模块。 According to How to import a module as
__main__
? 根据如何将模块作为
__main__
导入? , you can use the runpy
module to execute your module and supply whatever value of __name__
you like. ,您可以使用
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)
Now you can catch any uncaught exceptions that your module throws, and handle them however you like within the except
. 现在,您可以捕获模块引发的所有未捕获的异常,并根据需要在
except
处理它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.