おもこん

おもこんは「思いつくままにコンピュターの話し」の省略形です

Python初心者のお勉強ノート(6)標準入力と標準出力、ファイルの読み書き

標準入出力とは?

標準入力と標準出力は、Unix系のオペレーティングシステム(OS)の仕組みから来ています。 プログラムが起動されると、OSが以下の入出力先を自動的に用意します。

  • 標準入力(stdin): デフォルトでキーボードが割り当てられる。
  • 標準出力(stdout): デフォルトで画面が割り当てられる。

標準出力を使う

次の例では、標準出力に文字列を出力しています。

print("Hello world.")

このプログラムをhelloworld.pyという名前で保存し、コマンドラインからpy helloworld.pyと実行すると、print()関数の出力が画面に表示されます。

標準出力のリダイレクト

標準出力の出力先はコマンドラインで変更できます。 以下の例では、出力先をファイルに切り替えています。

> py helloworld.py > output.txt

このコマンドを実行すると、output.txtHello world.が保存されます。標準出力を使えば、コマンド起動時にその出力先を変えることができ、柔軟性が増します。

標準入力とinput()関数

input()関数とは?

input()関数は、標準入力(デフォルトではキーボード)からデータを受け取ります。次の例では、プロンプトを表示してユーザー入力を受け取ります。

x = input("x = ")

この例では、

  • 引数の文字列"x = "を画面に表示する。これが、入力を促すプロンプトになる
  • キーボードから入力した文字列がxに代入される。

実行例:

>>> x = input("x = ")
x = 100
>>> x
'100'
>>>

数値入力を受け取る

入力されたデータは文字列として扱われます。数値として計算する場合は、型変換を行う必要があります。

x = float(input("x = "))
y = float(input("y = "))
print(f"x + y = {x + y}")

print関数の中の文字列はf-stringと呼ばれる文字列リテラルです。 「フォーマット済み文字列リテラル」ということもありますが、長いのでf-stringが良いでしょう。 このリテラルを詳しく説明すると長くなるので、ここでは次の2点だけ確認しておきます。

  • ダブル・クォートの前にfをつける
  • ダブル・クォート内の文字列に、波カッコで囲んだ式を入れることができる。式は評価され、その値を文字列にしたものが埋め込まれる

sys.stdinを使った高度な標準入力

Pythonsys.stdinは、標準入力を直接扱うためのファイルオブジェクトです。これにより、キーボード入力だけでなく、リダイレクトされた入力データも扱えます。

標準入力をそのまま標準出力に流す

次のコードは、標準入力を1行ずつ読み取り、標準出力にそのまま出力します。

import sys

for line in sys.stdin:
    print(line, end="")

sys.stdinは、標準入力のストリームを直接扱うことができるオブジェクトです。 これをforループと組み合わせると、変数lineに1行ずつ入れてfor文のスイートを繰り返し実行することができます。

print関数の引数で「end=""」の部分は文字列の最後に空文字列を入れる、つまり何も入れないということを意味します。 「end=""」を省略すると、改行"\n"が入ります。 文字列lineには標準入力から入ってくる改行も含まれているので、print関数で新たに改行を入れるべきではありません。

このコードをstdin2stdout.pyというファイル名で保存し、入出力をリダイレクトして実行します。

> cat stdin2stdout.py | py stdin2stdout.py >stdin2stdout-copy.py
> cat stdin2stdout-copy.py
import sys

for line in sys.stdin:
    print(line, end="")
>

1行目でコピーをしています。 2行目ではコピー先のファイルをcatで表示しています。 これでコピーが正しくできていたことがわかります。

ファイル操作の基本

標準入出力は最初からオープンされているので、簡単に使えますが、自分でファイルを新たに使う場合は、オープンとクローズが必要です。

ファイルオブジェクトとは?

ファイルを操作するには、Pythonopen()関数を使い、ファイルオブジェクトを生成します。ファイルオブジェクトは、次のようなメソッドを提供します。

  • 読み取り: read(), readline(), readlines()
  • 書き込み: write(), writelines()
  • 位置変更: seek(), tell()

ファイルのオープンと読み書き

open()関数を使ってファイルを開きます。with構文を使えば、ファイルの自動クローズが保証されるため、安全です。

with open("example.txt", "r", encoding="utf-8") as f:
    content = f.read()
    f.write(content)
  • open関数でファイルを読み込みモード("r"がそれを表している)かつ、UTF-8のコーディングでオープンし、その情報をファイルオブジェクトにして変数fに代入する。
  • f.read関数でファイルを全部読み込み、それを文字列にし、content変数に代入する。
  • 文字列contentを標準出力にwriteメソッドで書きだす。
  • with文のスイートが終了し、外に出ると、ファイルは自動的にクローズされる。

ファイルオブジェクトの詳細

主なメソッド

ファイルオブジェクトは以下の操作をサポートします。

  • read(size): 指定サイズ分を読み取る。サイズを省略するとすべて読み取る。
  • readline(): 1行を読み取る。
  • readlines(): 全行をリストとして取得する。
  • write(string): 文字列をファイルに書き込む。
  • writelines(list): 複数の行をリストから書き込む。

ファイルコピーの例

次のコードは、指定されたファイルを別のファイルにコピーします。 このファイル名がcopy.pyだとします。

import sys

if len(sys.argv) != 3:
    print("Usage: python copy.py <source> <destination>")
    sys.exit(1)

src = sys.argv[1]
dst = sys.argv[2]

try:
    with open(src, "r", encoding="utf-8") as src_file:
        content = src_file.read()
    with open(dst, "w", encoding="utf-8") as dst_file:
        dst_file.write(content)
except FileNotFoundError:
    print(f"Error: The file '{src}' was not found.")
except IOError as e:
    print(f"IOError: {e}")
  • sys.exit(1)関数はプログラムを終了してコマンドに戻る。このとき、1という状態をシステム側に通知している。この数字はOS依存だが、通常0は「正常終了」を表し、それ以外は「異常終了(正常にプログラムが完了しなかった)」を表す。
  • ファイルの読み書きは実行時にエラーが起こる可能性があるので、例外処理を使っている。例外処理の内容は、読み込み時にファイルが見つからなかった場合(FileNotFoundError)とそれ以外の入出力エラー(IOError)に分けている

標準入出力とファイル操作のまとめ

  • 標準入出力:
    • print()input()で基本的な標準入出力が可能。
    • 高度な操作にはsys.stdinsys.stdoutを活用。
  • ファイル操作:
    • open()でファイルオブジェクトを生成し、読み書きを行う。
    • with構文を使うと、リソース管理が安全で簡単。
  • エラー処理:
    • ファイル操作では例外処理を適切に行うことで、エラーに対応する。

標準入出力やファイル操作は、Pythonプログラミングの基本ですから、しっかり押さえておくようにしましょう。