質問

これはからのフォローアップの質問です ここ 具体的にはそれに関して 答え.


Pythonモジュールから、私はaを呼び出しています こんにちは世界 単に印刷する実行可能 Hello World stdoutに。その出力をPythonにリダイレクトすることに興味があります StringIO そして走りました これ 答えはほとんど私を解決策にもたらします。

この答えの重要な部分は、このコードセグメントです。

1. def redirect_stdout():
2.     print "Redirecting stdout"
3.     sys.stdout.flush() # <--- important when redirecting to files
4.     newstdout = os.dup(1)
5.     devnull = os.open('/dev/null', os.O_WRONLY)
6.     os.dup2(devnull, 1)
7.     os.close(devnull)
8.     sys.stdout = os.fdopen(newstdout, 'w')

また、リダイレクトの前にstdoutを復元したいと思います。

質問

  1. 上記の機能では正確に何が起こっていますか?
    • とは dupdup2 やっていますか?
    • とは /dev/null?
    • 8行目は何をしていますか? (sys.stdout = os.fdopen(newstdout, 'w'))
  2. stdoutをaに保存するにはどうすればよいですか StringIO 物体?
  3. 電話の後にstdoutを復元するにはどうすればよいですか こんにちは世界 プログラム?

質問1と3の回答が簡単になるという質問1の答えが得られたら、かなり確信しています。とにかくそれらを投稿して、質問1の答えを私が行きたい方向に押し込むことにしました。

役に立ちましたか?

解決

内部で何が起こっているかを明確にする必要があるいくつかの追加のコメントを以下に書いた redirect_stdout 関数:

def redirect_stdout():
    print "Redirecting stdout"
    sys.stdout.flush() # <--- important when redirecting to files

    # Duplicate stdout (file descriptor 1)
    # to a different file descriptor number
    newstdout = os.dup(1)

    # /dev/null is used just to discard what is being printed
    devnull = os.open('/dev/null', os.O_WRONLY)

    # Duplicate the file descriptor for /dev/null
    # and overwrite the value for stdout (file descriptor 1)
    os.dup2(devnull, 1)

    # Close devnull after duplication (no longer needed)
    os.close(devnull)

    # Use the original stdout to still be able
    # to print to stdout within python
    sys.stdout = os.fdopen(newstdout, 'w')

注意すべき重要なことの1つは、プロセスが3つの異なるものを取得することです ファイル記述子 起動時にOSから:

  • stdin:0
  • stdout:1
  • stderr:2

コメントで説明したように、上記のコードは、stdoutのファイル記述子とファイル記述子の複製関数を利用して、Cコードをトリックして別のstdoutを使用し、Pythonコードの元のstdoutへの参照を保持しているため、印刷する。

他のヒント

/dev/null ブラックホールのように書かれたすべてを飲み込む特別なデバイスファイル(Unixのすべてがファイルです!)です。 dup ファイル記述子を複製します。 Windowsに慣れている場合、UNIXのファイル記述子は、開いたファイルを表す特別な整数であり、Windowsファイルのハンドルのようなものです。

プログラムが開設されています /dev/null 書き込みの場合(のみ)、ファイル記述子のコピーを取り、開いたファイルを閉じます(ファイル記述子を持つだけでファイルに書き込むのに十分であるため、リソースを開いたままにしておく必要はありません)。にファイル sys.stdout.

覚えて sys ファイルシステムなど、あらゆる種類のシステム固有のリソースを表すPythonモジュールです。だから、Unixで sys.stdout 表現します /dev/stdout つまり、システム STDOUT ストリーム。

だから、全体として、このコードはPythonをだまして、それを考えさせています /dev/null/STDOUT だから今、あなたのプログラムが書くたびに STDOUT たとえば、 print ステートメント(python3の関数)それからそれは本当に書くでしょう /dev/null そして、コンソールに結果のテキストが表示されることはありません。

見る マニュアルページ これらのPython関数の根底にあるCランタイム関数の場合。

基本的に、彼らはファイル記述子を複製し、新しいファイル記述子( dup())または通話で指定されたファイル記述子に dup2().

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top