Pythonのstdin, stdout,stderrとは何か?具体例を交えて分かりやすく解説する

スポンサーリンク

この記事を読み進める前に、stdinstdoutstderrという用語が何であるかを理解しましょう。

標準入力 – これは、ユーザプログラムがユーザから情報を得るために読み込むファイルハンドルです。

標準入力(stdin)に入力を行う。

標準出力 – ユーザプログラムが通常の情報をこのファイルハンドルに書き込む。

出力は標準出力(stdout)を介して返される。

標準エラー – ユーザプログラムは、このファイルハンドルにエラー情報を書き込みます。

エラーは標準エラー(stderr)を介して返される。

Pythonはstdin, stdout, stderrを表すファイルのようなオブジェクトを提供しています。

これらのオブジェクトを使って、プログラムの入出力をどのように扱うことができるかを見てみましょう。

スポンサーリンク

1. sys.stdin

Python の sys モジュールは stdin, stdout, stderr の 3 つのファイルオブジェクトを提供します。

入力ファイルオブジェクトには、sys.stdinを使います。

これはファイルに似ていて、他のファイルと同じように開いたり閉じたりすることができます

基本的な例を通して、このことを理解しましょう。

import sys
 
stdin_fileno = sys.stdin
 
# Keeps reading from stdin and quits only if the word 'exit' is there
# This loop, by default does not terminate, since stdin is open
for line in stdin_fileno:
    # Remove trailing newline characters using strip()
    if 'exit' == line.strip():
        print('Found exit. Terminating the program')
        exit(0)
    else:
        print('Message from sys.stdin: ---> {} <---'.format(line))

結果は以下の通りです。

Hi
Message from sys.stdin: ---> Hi
 <---
Hello from Python
Message from sys.stdin: ---> Hello from Python
 <---
exit
Found exit. Terminating the program

上の例では、 stdin から入力を読み込み、 exit という単語が現れるまでコンソール (stdout) にメッセージを表示し続けます。

NOTE: デフォルトの stdin ファイルオブジェクトをクローズすることは可能ですが、通常は行いません。

つまり、 stdin_fileno.close() は有効な Python コードなのです。

さて、stdin について少しわかったので、stdout に移動しましょう。

2. sys.stdout

出力ファイルオブジェクトには、sys.stdout を使用します。

これは sys.stdin と似ていますが、書き込まれたものを直接コンソールに表示します。

以下のスニペットは、sys.stdoutに書き込むと、コンソールに出力されることを示しています。

import sys
 
stdout_fileno = sys.stdout
 
sample_input = ['Hi', 'Hello from Python', 'exit']
 
for ip in sample_input:
    # Prints to stdout
    stdout_fileno.write(ip + '
'
)

結果は以下の通りです。

Hi
Hello from Python
exit

3. sys.stderr

これもコンソールに直接表示されるので、sys.stdoutと似ています。

しかし、違うのは例外とエラーメッセージだけを表示することです。

(これが標準エラーと呼ばれる理由です)。

例題で説明しましょう。

import sys
 
stdout_fileno = sys.stdout
stderr_fileno = sys.stderr
 
sample_input = ['Hi', 'Hello from Python', 'exit']
 
for ip in sample_input:
    # Prints to stdout
    stdout_fileno.write(ip + '
'
)
    # Tries to add an Integer with string. Raises an exception
    try:
        ip = ip + 100
    # Catch all exceptions
    except:
        stderr_fileno.write('Exception Occurred!
'
)

結果は以下の通りです。

Hi
Exception Occurred!
Hello from Python
Exception Occurred!
exit
Exception Occurred!

ご覧のように、すべての入力文字列に対して、整数に足そうとすると、例外が発生します。

このような例外はすべてキャッチして、sys.stderr を使って別のデバッグメッセージを表示します。

ファイルへのリダイレクト

stdin,stdout,stderr` のファイルハンドルは、他のファイル (file-handle) にリダイレクトすることができる。

これは、Logging などの他のモジュールを使用せずに、イベントをファイルに記録したい場合に便利でしょう。

以下のスニペットは、出力(stdout)を Output.txt というファイルにリダイレクトしています。

つまり、コンソールには何も表示されないということです。

これは、出力リダイレクトの本質です。

出力を他の場所に「リダイレクト」するのです。

import sys
 
# Save the current stdout so that we can revert sys.stdou after we complete
# our redirection
stdout_fileno = sys.stdout
 
sample_input = ['Hi', 'Hello from Python', 'exit']
 
# Redirect sys.stdout to the file
sys.stdout = open('Output.txt', 'w')
 
for ip in sample_input:
    # Prints to the redirected stdout (Output.txt)
    sys.stdout.write(ip + '
'
)
    # Prints to the actual saved stdout handler
    stdout_fileno.write(ip + '
'
)
 
# Close the file
sys.stdout.close()
# Restore sys.stdout to our old saved file handler
sys.stdout = stdout_fileno

出力先

root@ubuntu:~# python3 output_redirection.py
Hi
Hello from Python
exit
root@ubuntu:~# cat Output.txt
Hi
Hello from Python
exit

見ての通り、コンソールと Output.txt の両方に出力しています。

まず、オリジナルの sys.stdout ファイルハンドラーオブジェクトを別の Variable に保存します。

ファイルに書き込んだ後、ファイルを閉じるのと同じように、そのファイルがまだ開いていたので、ファイルを閉じることに注意してください。

最後に、 stdout_fileno 変数を使用して、 sys.stdout のハンドラをコンソールにリストアします。

入力とエラーのリダイレクションについても、 sys.stdoutsys.stdinsys.stderr に置き換えて、出力ではなく入力と例外を処理する同様の手順を踏むことができます。

まとめ

この記事では、Python の sys モジュールを使用して、 stdin, stdout, stderr を使用する方法について学びました。

また、ファイルへのリダイレクトやファイルからのリダイレクトに対応するファイルハンドラを操作する方法についても学びました。

タイトルとURLをコピーしました