Pythonを学んでいると、with文というものに出会うことがあります。このwith文は、特定の作業の前後で何かを自動的に行いたいときに便利な構文で、具体的にはファイルの開閉などによく使われます。

これを使うと、例えばファイルを開いて読み込んだ後に、自動的にそのファイルを閉じてくれたりします。
with open('example.txt', 'r') as my_file:
content = my_file.read()
このコードは、'example.txt'というファイルを開いて内容を読み込み、それをcontentという変数に保存していますが、最も重要な点はこの操作が終わった後にファイルが自動的に閉じられるということ。これは、with文を使っているからです。つまり、私たちはmy_file.close()と書く必要がありません。
このページではwith文の基本的な利用方法やファイルとの接続、またデータベースとの接続方法などを初心者でも理解できるようにわかりやすく解説します。
Pythonエンジニアを目指す方であれば知らないと恥ずかしい超・基本知識の1つです。是非最後までご覧ください。
Python:with文とは
with文は、ある作業を始める前と終わった後に自動的に何かを行うための便利な機能で、例えばファイルを開いて何か作業を行った後、そのファイルを自動的に閉じるといったような使い方が有名です。

この機能を使うことで、自分で細かい処理を書く手間が省け、コードもすっきりとします。
このwithがどのように動くのか、具体的な例を通して見ていきましょう。
with open('example.txt', 'r') as my_file:
content = my_file.read()
ここでwith open('example.txt', 'r') as my_file:という部分がwithを使った部分です。

この行は、「'example.txt'という名前のファイルを開き、その内容をmy_fileという名前で扱います」という意味になります。次の行のcontent = my_file.read()で、開いたファイルの中身を全て読み取り、その内容をcontentという変数に保存しています。
このコードの一番のポイントは、with文が終わると(この例ではcontent = my_file.read()の後)、開いたファイルが自動的に閉じられるというところです。つまり、my_file.close()と書く必要がないのです。

with文を使わないでファイルを開き、読み込む基本的なPythonのコードは以下の通り。
my_file = open('example.txt', 'r')
content = my_file.read()
my_file.close()
# 最後にmy_file.close()で開いたファイルを閉じている
このコードではwith文を利用していないので、最後に、my_file.close()で開いたファイルを閉じています。
これはこれで一見問題なさそうに見えるのですが、もし、何らかの理由でファイルを読み込む部分(content = my_file.read())でエラーが起きた場合、最後の行(my_file.close())が実行されません。そのため、ファイルが開いたままになってしまいます。

これは、他のプログラムがそのファイルを使用することを防ぐなど、様々な問題を引き起こす可能性があるため注意が必要な書き方になっている点に注意。
結論、with文はファイル操作を安全かつ簡潔に行うための非常に便利な機能であると言えます
with文はPythonにおけるファイル操作関連のプログラムの書き方の知識が前提となります。

open関数/read・write・closeメソッドなどのワードにピンとこない方は、まずはこちらの記事から。

もう1つ別の例を記載します。復習の意味を込めて、with文の利用方法や利点を見てみてください。
with構文を使わずにファイル操作を行う
# ファイルを新規作成
file = open("test.txt", "w",encoding='utf-8')
# writeメソッドを利用しファイルに文字を書き込む
file.write("Hello Python!")
# ファイルを閉じる
file.close()
①ファイルを開いて、②ファイル操作を行い、最後に③ファイルを閉じるという流れに沿って記述されています。
with構文を利用してファイル操作を行う
with open("test.txt", "w",encoding='utf-8') as file:
file.write("Hello Python!")
with文を利用すると以下のようにかなりすっきりと書くことができます。closeメソッドが省かれ、すっきり2行で記述されていることが分かります。念のため補足しますが、どちらも結果は全く同じです。

with文の基本的な仕組みを理解したところで、具体的な構文ルール:書き方をご説明しておきます。
Python:with文の構文ルール
with expression as variable:
# ブロック内のコード

上記のルールを確認しながら、with文のサンプルコードを確認していきましょう。
サンプル ファイル操作
with open('example.txt', 'r') as my_file:
content = my_file.read()
# expression:open('example.txt', 'r')
# →これにより、'example.txt'という名前のファイルを読み取りモードで開きます。
# variable:my_file
# →これは`open('example.txt', 'r')`によって開かれたファイルオブジェクトを参照する変数です。
サンプル ロックの取得と解放
import threading
lock = threading.Lock()
with lock:
# クリティカルセクション
print('Lock is held')
# expression:lock
# →この変数は`threading.Lock()`によって生成されたロックオブジェクトを参照しています。
# variable
# →ここでは`as`キーワードが省略されていますので、直接`expression`の参照を使用します。
サンプル データベーストランザクション
import sqlite3
conn = sqlite3.connect('example.db')
with conn:
cursor = conn.cursor()
cursor.execute('SELECT * FROM example_table')
# expression:conn
# →この変数は`sqlite3.connect('example.db')`によって生成されたデータベース接続オブジェクトを参照しています。
# variable:ここでも`as`キーワードが省略されていますので、直接`expression`の参照を使用します。
参考 変数の基本 / print関数 / メソッドの利用方法

上記の例から分かるように、expressionはwith文が制御するリソース(ファイル、ロック、データベース接続など)を生成する部分、variableはそのリソースを参照するための変数です。
そのリソースに対する操作はwithブロック内で行い、ブロックを抜けるときには自動的に後処理(ファイルを閉じる、ロックを解放する、トランザクションをコミットするなど)が行わるという点を押さえましょう。
with文のメリット

with文を利用するメリットについて。
実は、with文を使う目的はソースコードをすっきりさせるだけではないのです。
ファイルの閉じ忘れを防止(close漏れの防止)
ファイルの閉じ忘れにはデメリットが存在します。開けるファイル数には限りがあることや、開いたままのファイルが思わぬエラーを引き起こしてしまうためです。
そのため、ファイルを操作する場合には、必ずcloseメソッドでファイルを閉じるというのが原則です。
# ファイルを新規作成
file = open("test.txt", "w",encoding='utf-8')
# writeメソッドを利用しファイルに文字を書き込む
file.write("Hello Python!")
# ファイルを閉じる
file.close()
が、このファイルクローズは結構忘れられる場合が多いもの。特に初心者の方というよりは、ある程度Pythonに慣れてきた人に多く見受けられるのも現実。
with文を利用すれば、そもそもcloseメソッドは不要であるため、ファイルを閉じ忘れるということがありません。
with open("test.txt", "w",encoding='utf-8') as file:
file.write("Hello Python!")
with文自体にファイルクローズの仕組みが備わっているため、わざわざファイルを閉じる必要がないのです。
ソースの可読性が向上する
with文は、def文やif文などのように1つのブロックを生成します。
そのためwith文の中の処理がインデントされるため、ソースが読みやすくなります。(どこからどこまでが、with文の処理なのかが一目で分かりやすくなる。)
with open("test.txt", "w",encoding='utf-8') as file:
file.write("Hello Python!")
file.write("Hello Python!")
file.write("Hello Python!")
with open・・・・
初心者の方は、with文のメリットはこの2点を理解しておけばまずはOK。
実はこの他にもたくさんのメリットはあるため、是非積極的にwith文を利用していってみてください。
Pythonを1から学習したい方は

始めてPythonを勉強するのは結構難しいですよね。
でもその悩みを抱えているのは一人じゃありません。全てのPython使いが同じ道を進んできました。
Pythonをはじめとするプログラミングスキルを武器に、時間と場所に捉われない自由な生き方を目指してみませんか?今すぐ行動したい方は以下の記事をチェック!
読者料典 Python入門:学習カリキュラム ←こちらから!

