如果我有一个包含大量打印语句的函数:
即
def funA():
print "Hi"
print "There"
print "Friend"
print "!"
我想做的是这样的事情
def main():
##funA() does not print to screen here
a = getPrint(funA()) ##where getPrint is some made up function/object
print a ##prints what funA would normally print at this step
因此,当调用funcA时,它不会执行任何打印,而是输出到对象。然后我打印对象以获得结果。有办法做到这一点吗?我也不想触及原来的功能。
我希望这是有道理的。
答案 0 :(得分:8)
你可以完全按照你想要的那样 ,只要你不介意一点点语法差异:
import cStringIO
import sys
def getPrint(thefun, *a, **k):
savstdout = sys.stdout
sys.stdout = cStringIO.StringIO()
try:
thefun(*a, **k)
finally:
v = sys.stdout.getvalue()
sys.stdout = savstdout
return v
微小的区别在于您必须致电getPrint(funA)
,而不是 getPrint(funA())
- 即,您必须传递功能对象本身,不带可以立即调用它的尾随括号, getPrint
之前的可以发挥其魔力。
如果你绝对坚持这些额外的括号,那么getPrint
不能做所有所需的准备工作,并且必须通过其他代码来补充以正确准备(我强烈建议失去额外的括号,因此可以封装getPrint
内的所有功能!)。
答案 1 :(得分:3)
from cStringIO import StringIO
def getPrint(func, *args, **kwds):
old_stdout = sys.stdout
sys.stdout = StringIO()
try:
func(*args, **kwds)
except:
raise
else:
return sys.stdout.getvalue()
finally:
sys.stdout = old_stdout
#...
a = getPrint(funA) # notice no (), it is called by getPrint
print a.rstrip("\n") # avoid extra trailing lines
答案 2 :(得分:2)
最好的方法是做一个上下文管理器
from contextlib import contextmanager
import StringIO
import sys
@contextmanager
def capture():
old_stdout = sys.stdout
sys.stdout = StringIO.StringIO()
try:
yield sys.stdout
finally:
sys.stdout = old_stdout
现在您可以运行任何打印代码:
with capture() as c:
funA()
funB()
print 'HELLO!'
然后:
print c.getvalue()
答案 3 :(得分:1)
将sys.stdout
替换为file-like object。
答案 4 :(得分:1)
使用cStringIO(参见doc)。
from cStringIO import StringIO
old_stdout = sys.stdout
sys.stdout = mystdout = StringIO()
getPrint( funA() )
# use mystdout to get string
答案 5 :(得分:0)
最简单的方法是将funA()
更改为不打印任何内容,只是返回字符串值。
像这样:
def funA():
return "Hi\n" + "There\n" + "Friend\n" + "!\n"
# later:
print(funA())
收集字符串并打印它们总是很容易;在打印字符串时收集字符串很简单。
如果您拥有大量现有打印功能,那么,请使用此处提供的技巧之一来收集输出。