Разумный способ захвата Stdout для последующего воспроизведения? - PullRequest
1 голос
/ 09 сентября 2011

Как часть попытки протестировать побочный эффект унаследованной функции 'print to stdout', я хочу захватить stdout для последующего воспроизведения. Я использую mock.

цели (выполнить как можно больше!)

  • stdout все еще печатает, где обычно, но есть дополнительный рекордер
  • в идеале, это должно быть «исправлено» или происходит только в контексте

Моя реализация (ниже) имеет исправления, которые кажутся немного тяжелыми / грубыми. Есть ли более разумный способ сделать это? cStringIO? Какие-нибудь лучшие части mock я могу использовать вместо моего __getattr__ хака?

class StreamCapturing(object):
    def __init__(self, stream):
        self.captured = []
        self.stream = stream

    def __getattr__(self,attr):
        return getattr(self.stream,attr)

    def write(self, data):
        self.captured.append(data)
        self.stream.write(data)


import sys
import mock
with mock.patch('sys.stdout',StreamCapturing(sys.stdout)) as ctx:
    sys.stdout.write('a\n')
    print 'stdout'
    sys.__stdout__.write("the real one\n")
    print sys.stdout.captured
    sys.stdout.flush()

assert getattr(sys.stdout,'captured') is None

Ответы [ 2 ]

2 голосов
/ 09 сентября 2011

Вам даже не нужно сохранять предыдущий стандартный питон, он делает это за вас, и да, используйте cStringIO

import sys
from cStringIO import StringIO

sys.stdout = captured = StringIO()
print "test string"
# test stuff
captured = captured.getvalue()
sys.stdout = sys.__stdout__
print "captured",captured
0 голосов
/ 09 сентября 2011

Вам не нужно издеваться в этой ситуации:

saved_stdout = sys.stdout
sys.stdout = StreamCapturing(saved_stdout)

print "stdout"

captured = "".join(sys.stdout.captured)
sys.stdout=saved_stdout
print "captured: ", captured
...