如何在Python中重定向函数的打印输出。
在Python中,有时候我们希望将某个函数的打印输出重定向到其他地方,而不是默认的标准输出。这个问题的出现原因可能是因为我们想要将函数的打印输出保存到文件中,或者是用于测试函数的输出结果。下面是一种解决方法。
对于Python 3.4及以上的版本,可以使用标准库中提供的上下文管理器来实现输出重定向:
with contextlib.redirect_stdout(file_like_object): ...
如果你的Python版本较旧,可以自己编写一个上下文管理器来实现输出重定向。关键是将sys.stdout更新为你想要的文件对象(这是print语句写入的地方):
>>> import sys >>> import StringIO >>> stdout = sys.stdout # 保存真正的标准输出 >>> sys.stdout = StringIO.StringIO() # 选择一个文件对象来写入 >>> foo() >>> sys.stdout = stdout >>> foo() bar
可以使用contextlib模块创建一个上下文管理器,当进入上下文时,将stdout设置为你想要的值,然后在退出上下文时将stdout重置为原来的值。
下面是使用contextlib创建上下文管理器的简单示例:
import contextlib import sys .contextmanager def stdout_redirect(where): sys.stdout = where try: yield where finally: sys.stdout = sys.__stdout__ def foo(): print 'bar' # 使用StringIO示例 import StringIO with stdout_redirect(StringIO.StringIO()) as new_stdout: foo() new_stdout.seek(0) print "data from new_stdout:",new_stdout.read() new_stdout1 = StringIO.StringIO() with stdout_redirect(new_stdout1): foo() new_stdout1.seek(0) print "data from new_stdout1:",new_stdout1.read() # 使用文件对象示例 with open('new_stdout') as f: with stdout_redirect(f): foo() # 为了证明我们确实按照预期将stdout恢复了 print "Now calling foo without context" foo()
需要注意的是:
在Python 3.x中,StringIO.StringIO已经移动到io.StringIO。而在Python 2.x中,cStringIO.StringIO可能会稍微更高效。
对于上下文管理器的建议,可能是最简洁的方法。
在PEP 0343中可以找到更多示例和“临时重定向stdout”的详细信息。
从Python 3.4开始,也提供了contextlib.redirect_stdout()方法来实现输出重定向。
对于使用Python 3.X的人来说,可以参考stackoverflow.com/a/22434594/848277这个答案,因为之前的方法可能无法正常工作。