「ファイルを開いたあとにclose()を書き忘れてしまった」「サンプルコードに出てくるwithって結局なに?」——Pythonを学び始めると、こんな疑問にぶつかる方は多いのではないでしょうか。実はこのwith構文(withステートメント)を使うと、ファイルの後始末を自動でやってくれて、コードもぐっと読みやすくなります。
この記事では、Pythonのwith構文について、基本的な書き方からファイルの読み書き、withを使わない場合との違い、そして裏側で動いている「コンテキストマネージャ」の仕組みまで、初心者の方にも分かりやすく解説していきます。
コンテンツ
with構文(withステートメント)とは?
with構文とは、「開始」と「終了」がセットになっている処理を、安全に・自動的に後始末してくれる仕組みです。もっとも代表的な使いどころがファイル操作です。ファイルは「開いたら必ず閉じる」必要がありますが、withを使うとブロックを抜けるときに自動でファイルが閉じられます。
基本的な書き方は次のとおりです。
with open("sample.txt", "r", encoding="utf-8") as f:
data = f.read()
print(data)
# ここに来た時点で、ファイルfは自動的に閉じられているwithのうしろに「開始する処理」(ここではopen())を書き、asのうしろにその結果を受け取る変数(ここではf)を書きます。インデントされたブロックの中だけファイルが開いていて、ブロックを抜けると自動的に閉じられる、というのがポイントです。
ファイルを読み込んでみよう
それでは実際にファイルを読み込んでみましょう。open()の第2引数"r"は「読み込みモード(read)」を表します。1行ずつ処理したい場合は、for文でファイルオブジェクトをそのままループできます。
# sample.txt の中身を1行ずつ表示する
with open("sample.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip()) # strip()で行末の改行を除去
# 実行結果(sample.txtの中身が出力される)
# Python
# with構文
# 便利ですファイルを1行ずつ読み込んでfor文で回す処理は、Pythonの基本中の基本です。for文の使い方そのものに不安がある方は、Pythonのfor文・range関数の使い方もあわせて読んでみてください。また、CSVファイルからデータを読み込む実践例はPythonでWebページの見出しを抽出する方法(CSVファイルの扱いも解説)で紹介しています。
ファイルに書き込んでみよう
書き込みたいときは、モードを"w"(write)にします。"w"は既存の内容を上書きするモード、"a"(append)は末尾に追記するモードです。
# sample.txt に書き込む(既存の内容は上書きされる)
with open("sample.txt", "w", encoding="utf-8") as f:
f.write("1行目のテキスト
")
f.write("2行目のテキスト
")
# 末尾に追記したい場合はモードを "a" にする
with open("sample.txt", "a", encoding="utf-8") as f:
f.write("追記された行
")書き込む文字列に変数の値を埋め込みたいときは、f文字列を使うと便利です。f文字列の詳しい使い方はf文字列(f-string)の使い方で解説していますので、あわせてチェックしてみてください。
with構文を使わない場合との違い
withを使わずに同じことを書くと、次のようになります。自分でclose()を呼ばなければならない点に注目してください。
# withを使わない書き方(おすすめしません)
f = open("sample.txt", "r", encoding="utf-8")
data = f.read()
f.close() # 閉じ忘れに注意!この書き方には弱点があります。もしf.read()の途中でエラーが発生すると、f.close()が実行されず、ファイルが開きっぱなしになってしまうのです。これを防ぐには本来try〜finallyでしっかり閉じる必要があります。
# try〜finallyで確実に閉じる書き方
f = open("sample.txt", "r", encoding="utf-8")
try:
data = f.read()
finally:
f.close() # エラーが起きても必ず閉じられるwith構文は、このtry〜finallyと同じ「必ず後始末する」働きを、たった1行でやってくれているわけです。エラー処理そのものについて詳しく知りたい方は、Pythonの例外処理(try-except)の使い方もぜひ読んでみてください。
複数のファイルを同時に開く
1つのwithで複数のファイルを同時に開くこともできます。カンマで区切って並べるだけです。あるファイルを読み込んで、別のファイルに書き出す、といった処理がすっきり書けます。
# input.txtを読み込んでoutput.txtにコピーする
with open("input.txt", "r", encoding="utf-8") as fr, \
open("output.txt", "w", encoding="utf-8") as fw:
for line in fr:
fw.write(line)
# どちらのファイルもブロックを抜けると自動で閉じられるwith構文が動く仕組み(コンテキストマネージャ)
少し発展的な話になりますが、withが使えるオブジェクトには「コンテキストマネージャ」という共通のルールがあります。具体的には、__enter__(開始時の処理)と__exit__(終了時の処理)という2つのメソッドを持っているオブジェクトです。
withブロックに入るときに__enter__が、ブロックを抜けるときに__exit__が自動的に呼ばれます。ファイルのclose()は、この__exit__の中で実行されているのです。自分でクラスを作って__enter__と__exit__を定義すれば、独自のwith対応オブジェクトを作ることもできます。
class Timer:
def __enter__(self):
print("処理を開始します")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("処理を終了します")
with Timer():
print("メインの処理")
# 実行結果:
# 処理を開始します
# メインの処理
# 処理を終了しますもっと効率的にPythonを学びたい人へ
ここまでwith構文を解説してきましたが、「独学だとつまずいたときに質問できる相手がいなくて不安…」という方も多いと思います。そんなときは、プロの講師にマンツーマンで教えてもらえるプログラミングスクールを活用するのも一つの方法です。未経験からのPython習得や転職サポート、無料カウンセリングを用意しているスクールも多く、自分の理解度に合わせて効率よく学べます。まずは無料カウンセリングで学習プランだけ相談してみるのもおすすめです。
※本記事には広告(アフィリエイトリンク)を含みます。
Pythonプログラミング|マンツーマンレッスンで初めてをプロに育てる【Python Winner】![]()
まとめ
今回はPythonのwith構文について解説しました。最後に要点を振り返っておきましょう。
with構文は「開始」と「終了」がセットの処理を安全に扱える仕組みで、ファイル操作で特によく使うwith open(...) as f:と書くと、ブロックを抜けるときに自動でファイルが閉じられる- モードは読み込み
"r"・上書き"w"・追記"a"を使い分ける withはtry〜finallyと同じ「必ず後始末する」働きを1行で実現してくれる- カンマで区切れば複数ファイルを同時に開ける
- 裏側では
__enter__と__exit__を持つ「コンテキストマネージャ」が動いている
with構文を使いこなせるようになると、ファイル操作のコードが安全で読みやすくなります。ぜひ実際に手を動かして、ファイルの読み書きを試してみてくださいね。
ナノトイラボ 