Ruby の
while line = gets puts line end
は、コマンドライン引数で与えられたファイルを一つずつ開いて1行ずつ読み込み、出力するループである。コマンドライン引数でファイルを指定しなければ、標準入力から1行ずつ読み込む。
これと同じことをするための仕組みが Python の標準ライブラリの fileinput モジュールで提供されている:
import fileinput for line in fileinput.input(): print(line, end="") # または print(line.rstrip())
fileinput.input()
に引数でファイル名(のリスト)を与えれば、それが優先される。
Ruby の gets
と違い、ループの中で余分に行を読み込むことはできない。
標準入力だけ読めばよいなら、次のようにできる:
import sys for line in sys.stdin: print(line, end="") # または print(line.rstrip())
ループの中でも行を読み込める:
for line in sys.stdin: print("1:", line, end="") line = next(sys.stdin) print("2:", line, end="")
Python 3.8 以降の walrus operator :=
を使えばもっと柔軟なことができる。次の例は最初の空行が現れるまで標準入力を読んで出力する:
while line := next(sys.stdin).strip(): print(line)
入力中に UTF-8 として解釈できないバイト列があるとエラーになる。対策として、ほぼバイト列としてふるまう文字コード CP437 を指定すればよさそうだ(Python 3.7以降):
sys.stdin.reconfigure(encoding="cp437") sys.stdout.reconfigure(encoding="cp437")
ループではなく、標準入力から1行だけ読むには、次のようにする:
line = sys.stdin.readline()
プロンプトで入力を促すには、次のようにする:
n = int(input('正の整数を入力してください: '))
全部の行を行(文字列)のリストの形で読み込むには、次のようにする:
lines = sys.stdin.readlines()
全部の行を一つの文字列の形で読み込むには、次のようにする:
lines = sys.stdin.read()
標準入力でないファイルの場合は、次のようにする:
with open("filename", encoding="utf-8") as f: for line in f: print(line, end="")
あるいは
with open("filename", encoding="utf-8") as f: lines = f.readlines() # または f.read()
f.read()
は "1行目\n2行目\n..."
のような長い一つの文字列、f.readlines()
は ["1行目\n", "2行目\n", ...]
のような行のリストを返す。
コマンドラインで指定するファイルそれぞれについて上の処理を行うには次のようにすればよい:
import sys for filename in sys.argv[1:]: with open(filename, encoding="utf-8") as f: ...