この記事を読み進める前に、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 openfor 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))
|
結果は以下の通りです。
HiMessage from sys.stdin: ---> Hi
<---
Hello from Python
Message from sys.stdin: ---> Hello from Python
<---
exitFound 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 + ')
|
結果は以下の通りです。
HiHello 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!)
|
結果は以下の通りです。
HiException Occurred!Hello from Python
Exception Occurred!exitException 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 redirectionstdout_fileno = sys.stdout
sample_input = ['Hi', 'Hello from Python', 'exit']
# Redirect sys.stdout to the filesys.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 filesys.stdout.close()# Restore sys.stdout to our old saved file handlersys.stdout = stdout_fileno
|
出力先
root@ubuntu:~# python3 output_redirection.py
HiHello from Python
exitroot@ubuntu:~# cat Output.txt
HiHello from Python
exit |
見ての通り、コンソールと Output.txt の両方に出力しています。
まず、オリジナルの sys.stdout ファイルハンドラーオブジェクトを別の Variable に保存します。
ファイルに書き込んだ後、ファイルを閉じるのと同じように、そのファイルがまだ開いていたので、ファイルを閉じることに注意してください。
最後に、 stdout_fileno 変数を使用して、 sys.stdout のハンドラをコンソールにリストアします。
入力とエラーのリダイレクションについても、 sys.stdout を sys.stdin や sys.stderr に置き換えて、出力ではなく入力と例外を処理する同様の手順を踏むことができます。
まとめ
この記事では、Python の sys モジュールを使用して、 stdin, stdout, stderr を使用する方法について学びました。
また、ファイルへのリダイレクトやファイルからのリダイレクトに対応するファイルハンドラを操作する方法についても学びました。