Python封装一个函数来打印到变量

时间:2009-12-31 00:56:13

标签: python

如果我有一个包含大量打印语句的函数:

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时,它不会执行任何打印,而是输出到对象。然后我打印对象以获得结果。有办法做到这一点吗?我也不想触及原来的功能。

我希望这是有道理的。

6 个答案:

答案 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())

收集字符串并打印它们总是很容易;在打印字符串时收集字符串很简单。

如果您拥有大量现有打印功能,那么,请使用此处提供的技巧之一来收集输出。