sys.stdout を破壊せずに各関数呼び出しを復元せずに Python の関数の stdout を無音にする 質問する

sys.stdout を破壊せずに各関数呼び出しを復元せずに Python の関数の stdout を無音にする 質問する

Python で、次のように関数呼び出しをラップせずに stdout を無音にする方法はありますか?

元の壊れたコード:

from sys import stdout
from copy import copy
save_stdout = copy(stdout)
stdout = open('trash','w')
foo()
stdout = save_stdout

編集: Alex Martelli のコードを修正しました

import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout

この方法はうまくいきますが、非常に非効率なようです。もっているもっと良い方法があると思います。何かアイデアはありますか?

ベストアンサー1

変数に代入しても、 containsステートメントstdoutを仮定すると、何の効果もありません。これは、決してインポートしてはいけない理由のもう一つの例です。fooprint内部モジュール (ここで行っているように) ではなく、常にモジュール全体 (修飾名を使用) です。copyちなみに、 は無関係です。スニペットの正しい同等物は次のとおりです。

import sys
save_stdout = sys.stdout
sys.stdout = open('trash', 'w')
foo()
sys.stdout = save_stdout

コードが正しい場合は、それをよりエレガントにしたり高速化したりするタイミングです。たとえば、ファイル「trash」の代わりに、メモリ内のファイルのようなオブジェクトを使用できます。

import sys
import io
save_stdout = sys.stdout
sys.stdout = io.BytesIO()
foo()
sys.stdout = save_stdout

エレガンスのために、コンテクストが最適です。例:

import contextlib
import io
import sys

@contextlib.contextmanager
def nostdout():
    save_stdout = sys.stdout
    sys.stdout = io.BytesIO()
    yield
    sys.stdout = save_stdout

このコンテキストを定義したら、stdoutを出力したくないブロックでは、

with nostdout():
    foo()

さらに最適化するには、sys.stdout を no-op メソッドを持つオブジェクトに置き換えるだけですwrite。例:

import contextlib
import sys

class DummyFile(object):
    def write(self, x): pass

@contextlib.contextmanager
def nostdout():
    save_stdout = sys.stdout
    sys.stdout = DummyFile()
    yield
    sys.stdout = save_stdout

の以前の実装と同じように使用できますnostdout。これよりクリーンで高速な方法はないと思います;-)。

おすすめ記事