Python の contextlib.redirect_stdout で出力先を変える
contextlib.redirect_stdout と redirect_stderr を使うと、標準出力や標準エラー出力の出力先を一時的に変更できます。テストやログ取得、出力のキャプチャに便利です。
redirect_stdout の基本
標準出力をファイルやバッファにリダイレクトします。
from contextlib import redirect_stdout
import io
# StringIO にリダイレクト
f = io.StringIO()
with redirect_stdout(f):
print("この出力はキャプチャされる")
print("複数行も OK")
output = f.getvalue()
print(f"キャプチャ結果:\n{output}")with ブロックを抜けると、標準出力は自動的に元に戻ります。
ファイルへのリダイレクト
出力をファイルに保存することもできます。
from contextlib import redirect_stdout
with open("output.txt", "w") as f:
with redirect_stdout(f):
print("この出力はファイルに書き込まれる")
for i in range(5):
print(f"Line {i}")redirect_stderr
標準エラー出力も同様にリダイレクトできます。
from contextlib import redirect_stderr
import io
import sys
f = io.StringIO()
with redirect_stderr(f):
print("これはエラー出力", file=sys.stderr)
error_output = f.getvalue()
print(f"エラー出力: {error_output}")両方を同時にリダイレクト
標準出力と標準エラー出力を同時にリダイレクトすることもできます。
from contextlib import redirect_stdout, redirect_stderr
import io
import sys
stdout_buf = io.StringIO()
stderr_buf = io.StringIO()
with redirect_stdout(stdout_buf), redirect_stderr(stderr_buf):
print("標準出力")
print("エラー出力", file=sys.stderr)
print(f"stdout: {stdout_buf.getvalue()}")
print(f"stderr: {stderr_buf.getvalue()}")実用例:関数の出力をキャプチャ
print() を使う関数の出力をキャプチャしてテストできます。
from contextlib import redirect_stdout
import io
def greet(name):
print(f"Hello, {name}!")
print("Welcome!")
def test_greet():
f = io.StringIO()
with redirect_stdout(f):
greet("Alice")
output = f.getvalue()
assert "Hello, Alice!" in output
assert "Welcome!" in output
print("テスト成功")
test_greet()実用例:サードパーティライブラリの出力を抑制
うるさいライブラリの出力を一時的に抑制します。
from contextlib import redirect_stdout, redirect_stderr
import os
# /dev/null (Unix) や NUL (Windows) に捨てる
with open(os.devnull, "w") as devnull:
with redirect_stdout(devnull), redirect_stderr(devnull):
# この中の出力は表示されない
print("これは表示されない")
noisy_library_function()出力を抑制するヘルパー
何度も使う場合はヘルパー関数を作ると便利です。
from contextlib import contextmanager, redirect_stdout, redirect_stderr
import os
@contextmanager
def suppress_output():
with open(os.devnull, "w") as devnull:
with redirect_stdout(devnull), redirect_stderr(devnull):
yield
with suppress_output():
print("これは表示されない")
print("これは表示される")注意点
リダイレクトは sys.stdout / sys.stderr への書き込みにのみ影響します。C拡張モジュールが直接ファイルディスクリプタに書き込む場合は、この方法ではキャプチャできません。
# Python の print() → キャプチャできる
# C拡張の直接出力 → キャプチャできない場合があるテストやログ取得で redirect_stdout を活用すると、出力に依存した処理を柔軟に制御できます。



