この記事を読み進める前に、stdin
、stdout
、stderr
という用語が何であるかを理解しましょう。
標準入力 – これは、ユーザプログラムがユーザから情報を得るために読み込むファイルハンドルです。
標準入力(stdin)に入力を行う。
標準出力 – ユーザプログラムが通常の情報をこのファイルハンドルに書き込む。
出力は標準出力(stdout)を介して返される。
標準エラー – ユーザプログラムは、このファイルハンドルにエラー情報を書き込みます。
エラーは標準エラー(stderr)を介して返される。
Pythonはstdin, stdout, stderrを表すファイルのようなオブジェクトを提供しています。
これらのオブジェクトを使って、プログラムの入出力をどのように扱うことができるかを見てみましょう。
この記事もチェック:Pythonでinput関数を使ってユーザーからの標準入力を変数に格納する方法
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.stdout
を sys.stdin
や sys.stderr
に置き換えて、出力ではなく入力と例外を処理する同様の手順を踏むことができます。
まとめ
この記事では、Python の sys
モジュールを使用して、 stdin
, stdout
, stderr
を使用する方法について学びました。
また、ファイルへのリダイレクトやファイルからのリダイレクトに対応するファイルハンドラを操作する方法についても学びました。