ユーニックス総合研究所

  • home
  • archives
  • python-std-in-out-err

Pythonで扱う標準入力・標準出力・標準エラー出力(sys.stdin, sys.stdout, sys.stderr)

  • 作成日: 2021-06-18
  • 更新日: 2023-12-26
  • カテゴリ: Python

Pythonで標準入力・標準出力・標準エラー出力を扱う

Pythonでは標準の入力先として標準入力を表すファイルオブジェクトを扱うことができます。
他にも標準の出力先、標準のエラー出力先のファイルオブジェクトを扱えます。

結論から言うとそれぞれのファイルオブジェクトは↓のように扱います。

import sys  


text = sys.stdin.read()  # 標準入力から読み込み  
sys.stdout.write(text)  # 標準出力へ書き込み  
sys.stderr.write('failed')  # 標準エラー出力へ書き込み  

この記事では標準入力・出力・エラー出力について具体的に↓を見ていきます。

  • 標準入力とは?
  • 標準出力とは?
  • 標準エラー出力とは?
  • sys.stdinで標準入力を読み込む
  • sys.stdoutで標準出力へ書き込む
  • sys.stderrで標準エラー出力へ書き込む

関連記事

標準入力とは?

標準入力とは「標準の入力先」という意味です。

🦝 < まんまですね

入力先とは、何か外から中へ向かってデータを入れる時のデータを入れる元になるところをいいます。
お風呂に湯を張る場合は、お湯の出る蛇口が標準の入力先にになります。

プログラムでは何か外部から入力を得るときに、この標準入力を使うことが多いです。
この標準入力は通常はキーボードに繋がっています。
つまりキーボードから何かカタカタと打ち込んだら、そのタイプしたキーを標準入力から読み込めるということになります。

標準入力はパイプなどではプロセスの標準出力へ繋げるなど、自由に変更することができます。
この仕組みによってUNIX系のシステムではパイプを使って多様なジョブを実行することができます。

Pythonでは標準入力はファイルオブジェクトとして表現されます。
つまり標準入力のファイルオブジェクトからデータを読み込むことで、キーボードから打ち込まれたデータを読み取ることができるということになります。
Pythonでは標準入力を表すオブジェクトはsysモジュールに保存されています。
stdinというファイルオブジェクトがそれです。

stdinstandard input(標準入力)の略です。

標準出力とは?

標準出力とは「標準の出力先」という意味です。

これは通常、ディスプレイになります。
つまり標準出力先へ何かデータを転送したら、そのデータはディスプレイに表示されるということになります。

標準出力は通常のデータを書き込みます。エラーなどのデータは標準エラー出力へ書き込むのが通常です。

標準出力先も自由に変更することができます。
たとえばプロセスAの標準出力をプロセスBの標準入力へ繋げるということも出来ます。
こうするとプロセスBはプロセスAの出力を読み込んで処理を行うことができます。

🐭 < パイプの仕組みですね

Pythonでは標準出力を表すオブジェクトはsysモジュールに保存されています。
stdoutというファイルオブジェクトがそれです。

stdoutstandard output(標準出力)の略です。

標準エラー出力とは?

標準エラー出力とは「標準のエラーの出力先」という意味です。

標準出力にはエラー以外のデータを書き込みますが、標準エラー出力にはエラーに関連するデータを書き込むのが通常です。
なぜ標準出力とエラー出力が分かれているのかと言いますと、プロセスの出力をエラーとそれ以外に分離する場合に便利だからです。

たとえばUNIX系でよく使われるBashというシェルでは、↓のようにするとスクリプトの標準出力をファイルに保存することができます。

$ python script.py 1> stdout.txt  

↑の場合、標準出力のみがstdout.txtに保存され、標準エラー出力はそのままディスプレイに表示されます。
またエラー出力も↓のようにファイルへ出力することができます。

$ python script.py 2> stderr.txt  

このようにエラーである出力とエラーでない出力を別々に分離できることで、プログラムのデバッグが容易になったり、あるいは不要な情報をそぎ落とすことができます。
たとえばスクリプトの出力にエラー表示が出ていてそれを取り除きたい時は、↓のように標準エラー出力を/dev/nullに繋げます。

$ python script.py 2> /dev/null  

こうすると標準エラー出力への出力は/dev/nullへ捨てられて、ディスプレイには必要な情報だけが残ります。

Pythonでは標準エラー出力を表すオブジェクトはsysモジュールに保存されています。
stderrというファイルオブジェクトがそれです。

stderrstandard error(標準エラー)の略です。

sys.stdinで標準入力を読み込む

標準入力からデータを読み込むにはsys.stdinオブジェクトを参照します。

stdinはファイルオブジェクトです。

import sys  


print(type(sys.stdin))  
# <class '_io.TextIOWrapper'>  

TextIOWrapperにはread()readlines()などのデータ読み込み用メソッドがあります。
これらのメソッドを使うことで標準入力からデータを読み込むことができます。

read()で全データを読み込み

↓のようにstdin.read()は標準入力からすべてのデータを読み込みます。

data = sys.stdin.read()  
print(data)  

これはstdinのストリーム位置がEOFに達するまで読み込まれます。

$ echo abc | python stdinread.py  
abc  

↑のecho abc | python stdinread.pyというのはパイプを使った書き方です。
これはechoabcという文字列を標準出力へ出力して、それをstdinread.pyの標準入力へ繋げています。
結果sys.stdin.read()abcというデータが読み込まれます。

read(1)で1文字だけ読み込む

↓のようにstdin.read(1)とやると標準入力から1文字だけデータを読み込みます。

c = sys.stdin.read(1)  
print(c)  

read()は第1引数の整数の値だけデータを読み込み、ストリーム位置を進めます。

$ echo abc | python stdinreadone.py  
a  

read(1)ですべてのデータをループで読み込む

stdin.read(1)をループで実行するとすべてのデータを1文字ずつ読み込むことができます。

while True:  
    c = sys.stdin.read(1)  
    if not len(c):  
        break  
    print(c)  

read(1)EOFに達した場合は空文字列を返します。
そのため↑のようにcの長さが0になったらループから抜けるようにしています。

$ echo abc | python stdinreadoneloop.py  
a  
b  
c  

readlines()で複数行を読み込む

stdin.readlines()を使うと標準入力から複数行を読み込むことができます。
これの返り値はリストです。

lines = sys.stdin.readlines()  
print(lines)  
$ echo $'abc\ndef\nghi' | python stdinreadlines.py  
['abc\n', 'def\n', 'ghi\n']  

↑のecho $'abc\ndef\nghi'というのは見慣れない書き方ですが、こうするとechoに改行を含ませることができます。
↑のようにreadlines()は行末の改行を除去しないので注意が必要です。

readline()で一行読み込む

stdin.readline()を使うと標準入力から一行読み込むことができます。

line = sys.stdin.readline()  
print(line)  
$ echo $'abc\ndef\nghi' | python stdinreadline.py  
abc  

readline()とループで全行を読み込む

stdin.readline()をループで使うと一行ずつデータを読み込むことができます。

import sys  


while True:  
    line = sys.stdin.readline()  
    if not len(line):  
        break  
    print(line)  

readline()EOFに達すると空文字列を返します。
ですので↑のようにlineの長さが0だったらループから抜けるようにしています。

$ echo $'abc\ndef\nghi' | python stdinreadlineloop.py  
abc  

def  

ghi  

↑の出力を見てもわかるようにreadline()は行末の改行を除去しません。
行末の改行が不要な場合はline.rstrip()などを行います。

input()で一行読み込み

組み込み関数のinput()は内部でsys.stdinオブジェクトを使っています。
input()は標準入力から一行データを読み込みます。

line = input()  
print(line)  
$ echo $'abc\ndef\nghi' | python input.py  
abc  

sys.stdoutで標準出力へ書き込む

標準出力へデータを書き込むにはsys.stdoutオブジェクトのメソッドを使います。

write()writelines()などのメソッドを使うことで標準出力へデータを書き込むことができます。
sys.stdoutもファイルオブジェクトです。

import sys  


print(type(sys.stdout))  
# <class '_io.TextIOWrapper'>  

write()でデータを書き込み

stdout.write()に文字列を渡すとその文字列を標準出力へ書き込むことができます。

import sys  


sys.stdout.write('本日は晴天なり')  
# 本日は晴天なり  

write()print()と違って行末に改行を付加しません。

writelines()で行を書き込み

stdout.writelines()に文字列の入ったリストを渡すと、その文字列を標準出力へ書き込むことができます。

sys.stdout.writelines(['abc', 'def', 'ghi'])  
# abcdefghi  

各行の行末には自動的に改行は付加されません。
各行の行末で改行させたい場合は改行を付加してください。

print()でデータを書き込む

組み込み関数のprint()は内部でsys.stdoutオブジェクトを使っています。
print()はデフォルトでは自動で改行を付加します。

print('本日は晴天なり')  
# 本日は晴天なり  

print()の使うファイルオブジェクトを変更したい場合はfileキーワード引数にファイルオブジェクトを指定します。

print('本日は晴天なり', file=sys.stderr)  
# 本日は晴天なり  

sys.stderrで標準エラー出力へ書き込む

標準エラー出力へデータを書き込むにはsys.stderrオブジェクトのメソッドを使います。

これはsys.stdoutオブジェクトのメソッドと等しいものです。
書き込み先だけ標準エラー出力になります。

sys.stderrもファイルオブジェクトです。

import sys  


print(type(sys.stderr))  
# <class '_io.TextIOWrapper'>  

write()でデータを書き込む

前述のstdout.write()を参照してください。

writelines()でデータを書き込む

前述のstdout.writelines()を参照してください。

おわりに

今回はPythonの標準入力・標準出力・標準エラー出力について見てみました。
これらのファイルオブジェクトはPythonでは簡単に扱うことができます。

🦝 < 標準にこだわる

🐭 < えらい