164

オブジェクトに対して何かを行う Python ライブラリを使用しています

do_something(my_object)

そしてそれを変更します。そうしている間、いくつかの統計が標準出力に出力されます。この情報を把握したいと思います。適切な解決策はdo_something()、関連する情報を返すように変更することです。

out = do_something(my_object)

do_something()しかし、開発者がこの問題に到達するまでにはしばらく時間がかかります。do_something()回避策として、 stdout への書き込みを解析することを考えました。

コード内の 2 点間の stdout 出力をキャプチャするにはどうすればよいですか。

start_capturing()
do_something(my_object)
out = end_capturing()

?

4

5 に答える 5

237

このコンテキストマネージャーを試してください:

from io import StringIO 
import sys

class Capturing(list):
    def __enter__(self):
        self._stdout = sys.stdout
        sys.stdout = self._stringio = StringIO()
        return self
    def __exit__(self, *args):
        self.extend(self._stringio.getvalue().splitlines())
        del self._stringio    # free up some memory
        sys.stdout = self._stdout

使用法:

with Capturing() as output:
    do_something(my_object)

output関数呼び出しによって出力された行を含むリストになりました。

高度な使い方:

明らかではないかもしれないことは、これが複数回実行され、結果が連結される可能性があるということです:

with Capturing() as output:
    print('hello world')

print('displays on screen')

with Capturing(output) as output:  # note the constructor argument
    print('hello world2')

print('done')
print('output:', output)

出力:

displays on screen                     
done                                   
output: ['hello world', 'hello world2']

更新: Python 3.4 に追加さredirect_stdout()れましcontextlibた (とともにredirect_stderr())。したがって、それを使用io.StringIOして同様の結果を得ることができます (ただしCapturing、コンテキスト マネージャーと同様にリストであることは間違いなくより便利です)。

于 2013-05-15T17:43:39.907 に答える