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
を仮定すると、何の効果もありません。これは、決してインポートしてはいけない理由のもう一つの例です。foo
print
内部モジュール (ここで行っているように) ではなく、常にモジュール全体 (修飾名を使用) です。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
。これよりクリーンで高速な方法はないと思います;-)。