ファイルを読み書きする

INPUT · スライド

かならず閉じてもらう

01 / 07

閉じ忘れは、気をつけても起きる

前のレッスンの最後の問題では close を4回書いた。ファイルが増えるほど回数も増える。気をつけていても、いつか忘れる。

もっと困るのは、close の手前でエラーが起きたときだよ。プログラムはそこで止まるので、close の行までたどり着けない。

「忘れないようにがんばる」ではなく、そもそも忘れようがない形にしたい。それが with(ウィズ)だよ。

02 / 07

with の形

with open("memo.txt") as f: と書いて、行の終わりを : で閉じ、次の行から字下げする。if や for と同じ、おなじみの形だね。

字下げしたブロックを抜けたところで、Python が自動的に閉じてくれる。close を書く場所はもう無いよ。

with open("memo.txt", "w") as f:    f.write("あさ")with open("memo.txt") as f:    print(f.read())

実行結果

あさ

03 / 07

本当に閉じているか確かめる

ファイルには closed という札が付いていて、閉じているかどうかを教えてくれる。ブロックを抜けたあとで見てみよう。

True と出た。書かなかった close が、たしかに実行されているよ。

with open("memo.txt", "w") as f:    f.write("あさ")print(f.closed)

実行結果

True

04 / 07

as のうしろは、ただの変数名

as f は「開いたファイルに f という名前をつける」という意味。f でなければいけない決まりは無いよ。

読みやすい名前を付けていい。ただし Python のコードでは f がとても多いので、他人のコードを読むときは f を見てファイルだと思えるようにしておこう。

with open("memo.txt", "w") as fairu:    fairu.write("ひる")with open("memo.txt") as fairu:    print(fairu.read())

実行結果

ひる

05 / 07

途中でエラーが起きても閉じてくれる

ここが with のいちばんありがたいところ。ブロックの中でエラーが起きても、抜けるときにちゃんと閉じてくれる。

下の例では、読んだあとでわざと 1 / 0 を書いてエラーを起こしている。except で受け止めたあとに closed を見ると True。手で close を書いていたら、ここは閉じられないままだったよ。

with open("memo.txt", "w") as f:    f.write("あさ")try:    with open("memo.txt") as f:        print(f.read())        print(1 / 0)except ZeroDivisionError:    print("わりざんでしっぱい")print(f.closed)

実行結果

あさ
わりざんでしっぱい
True

06 / 07

ブロックは短くする

with のブロックの中にいるあいだ、ファイルは開きっぱなしだ。だから中でやるのは読み書きだけにして、続きの処理は外でやるのがきれいな書きかただよ。

読んだ内容を変数に入れておけば、ブロックを抜けたあとも使える。閉じたファイルの中身が消えるわけではないからね。

with open("memo.txt", "w") as f:    f.write("りんご")with open("memo.txt") as f:    honbun = f.read()print(f"ないようは{honbun}")

実行結果

ないようはりんご

07 / 07

まとめ

with はこういう道具だった。

  • with open(...) as f: と書いて字下げする
  • ブロックを抜けるときに Python が閉じる
  • 途中でエラーが起きても閉じてくれる

これから先、ファイルを開くときは必ず with と思っていい。実際のプログラムでも、open を裸で書いているコードはほとんど見かけないよ。

次は、読みかたのほうを深めよう。中身を丸ごとではなく、1行ずつ扱えるようにするよ。