python捕获其他模块生成的sys.stdout和sys.exit
我有两个脚本如下,但我不能修改foo.py 我已经在bar.py中编写了代码来捕获foo.py生成的输出,以便在输出到终端之前修改输出 但是,捕获不起作用。我做错了什么python捕获其他模块生成的sys.stdout和sys.exit,python,output,capture,sys,Python,Output,Capture,Sys,我有两个脚本如下,但我不能修改foo.py 我已经在bar.py中编写了代码来捕获foo.py生成的输出,以便在输出到终端之前修改输出 但是,捕获不起作用。我做错了什么 foo.py ---- import sys def some_func(): sys.stdout.write("hello") sys.stdout.flush() def foo(): some_func() sys.exit(1) 这是我可以修改的模块: ba
foo.py
----
import sys
def some_func():
sys.stdout.write("hello")
sys.stdout.flush()
def foo():
some_func()
sys.exit(1)
这是我可以修改的模块:
bar.py
----
import io
from contextlib import redirect_stdout
from foo import foo
f = io.StringIO()
with redirect_stdout(f):
foo()
s = f.getvalue()
print(s)
编辑:
最终解决方案
import io
from contextlib import redirect_stdout
from foo import foo
def capture_output(func):
f = io.StringIO()
try:
with redirect_stdout(f):
func()
except SystemExit:
return f.getvalue()
capture_output(foo)
问题是调用in
foo.py
在bar.py
中调用foo()
,然后到达foo()
函数的最后一行时,解释器立即退出,调用foo()
后的bar.py
的其余部分不会执行。因此,您正在正确地捕获标准输出——它只是在程序退出之前没有打印出来
如果您无法更改的文件实际上包含对sys.exit(1)
的直接调用,并且您希望在不退出的情况下处理该调用,则可以将对foo()
的调用包装在try
/块中,但块除外。但是,根据实际调用的sys.exit(1)
的上下文,使用类似于
编辑:
回复:您的评论如下
如果输出可能指向sys.stdout
或sys.stderr
,则应说明其中一个。例如,你可以做:
从contextlib导入重定向\u stdout,重定向\u stderr
tmp_stdout,tmp_stderr=StringIO(),StringIO()
使用redirect_stdout(tmp_stdout),redirect_stderr(tmp_stderr):
foo()
tmp_stdout,tmp_stderr=tmp_stdout.getvalue(),tmp_stderr.getvalue()
是--sys.exit()
试试看:
#你的代码在这里
除系统退出外:
通过
虽然我觉得这有点粗略。通常,非零退出代码表示程序中某个地方出现了错误,因此在绝大多数情况下,故意引发的sys.exit(1)
可能不是您想要默默抑制的
这是您可以尝试的:
import sys
import os
import importlib
# foo.py
def some_func():
sys.stdout.write("hello")
sys.stdout.flush()
def foo():
some_func()
sys.exit(1)
# bar.py
original = sys.stdout
def start_capture():
sys.stdout = open('tmpfile', 'w')
def stop_capture():
sys.stdout.close()
sys.stdout = original
data = ""
with open('tmpfile', 'r') as f:
data = f.read()
os.remove('tmpfile')
return data
start_capture()
try:
foo()
except SystemExit:
print('\nFoo Exit!\n')
print(stop_capture())
出于演示目的,我将foo.py放在同一个文件中,但主要部分是重定向stdout我无法修改foo,这就是我试图捕获的内容。是否有方法捕获在其他模块中调用的sys.exit,实际上不是exit,而是处理它?@darkman请检查我的答案once@darkman谢谢你的澄清,我已经更新了我的答案谢谢你的代码,因为它可以完成工作,所以我感谢你的贡献,但实际上@paxton4416更适合我的需要。