Pythonの「with構文」とJavaの「try-with-resources構文」の違いと共通点をわかりやすく解説!

こんにちは。ゆうせいです。

今回は 「Pythonのwith構文 について、Javaを学んできた新人エンジニアの方に向けて、特に Javaのtry-with-resources構文との比較 を交えながら丁寧に説明していきます。

似ているようで微妙に仕組みが違うこの2つ。
なんとなく「自動でリソース閉じてくれるんでしょ?」と理解していませんか?

たしかに正しいですが、それだけでは不十分です!

文法、内部的な処理、そして拡張性の違いまで、例えを交えつつ解説していきますね。


Pythonのwith構文とは?

一言で言えば「リソース管理の自動化」

Pythonのwith構文は、ファイルやデータベースのような「使い終わったら閉じる必要があるリソース」の管理を自動で行ってくれる構文です。

例で確認してみましょう!

with open("sample.txt", "r") as file:
    contents = file.read()
    print(contents)

このコード、Java風に書くとどうなるかというと…


Javaのtry-with-resourcesとは?

try (BufferedReader br = new BufferedReader(new FileReader("sample.txt"))) {
    String line;
    while ((line = br.readLine()) != null) {
        System.out.println(line);
    }
} catch (IOException e) {
    e.printStackTrace();
}

Javaでも同じように、try-with-resourcesによってファイルを自動的にクローズしていますね!


共通点と違いをまとめてみましょう!

比較項目Python(with構文)Java(try-with-resources)
主な目的リソースの自動管理リソースの自動管理
対象となるリソース__enter____exit__を実装したオブジェクトAutoCloseableインターフェースを実装したオブジェクト
リソースの自動クローズ__exit__が実行されるclose()メソッドが自動で呼び出される
例外の補足任意(tryexceptと組み合わせ可能)catch節が必須で一般的
カスタム対応のしやすさクラスに__enter__/__exit__を定義すればOKクラスがAutoCloseableを実装すればOK

Pythonの内部的な仕組み(少し専門的な話)

withの裏では何が起こっているのか?

実はこの構文、裏側では以下のようなことをしています:

context = open("sample.txt", "r")
try:
    file = context.__enter__()
    # 本体の処理
finally:
    context.__exit__(None, None, None)

つまり、Pythonのwith構文は 「前処理→処理→後処理」 をオブジェクトに任せているわけです。

この仕組みを使えば、自分で定義したクラスにも使えます!


具体例:カスタムクラスを使ってみよう

class MyResource:
    def __enter__(self):
        print("リソースを初期化します")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("リソースを解放します")

with MyResource() as r:
    print("リソースを使用中")

実行結果:

リソースを初期化します
リソースを使用中
リソースを解放します

このように、自作クラスでもwith構文が使えるんです!


どっちが優れているの?

一概に「どちらが優れている」とは言えませんが、以下のような違いがあります:

Pythonの方が柔軟で簡潔

Pythonでは、try-catchを書かなくても最低限のリソース管理が可能で、文法もシンプルです。
カスタムコンテキストマネージャも比較的簡単に作れます。

Javaは型と例外処理がしっかりしている

Javaはコンパイル時にリソースの扱いを厳密にチェックするため、安全性が高いです。
ただし、コード量はやや多くなりがちです。


例え話で理解しよう!

Pythonは「掃除ロボット付きの部屋」

入室(__enter__)したら、掃除ロボットが自動で動き始め、退室時(__exit__)には自動で後片付けしてくれる。
使う人は気にしなくてOK。

Javaは「チェックリスト付きの部屋」

部屋に入る前に「使用方法確認」、退出時は「この順番で片付けをしてください」といった明文化された手順書がある。
確実だけど、ちょっと堅苦しい印象もありますね。


今後の学習の指針

  • Pythonのcontextlibモジュールには、さらに高度なwith構文の使い方(デコレータ型など)があります。
  • async withを使うと、非同期処理でもwith構文を活用できます。
  • JavaのAutoCloseableの挙動も改めて確認しておくと理解が深まります。

Pythonに慣れてきたら、自分でもオリジナルのコンテキストマネージャを作ってみるのがおすすめです!

仕組みを理解すれば、コードの安全性と可読性がぐっと高まりますよ。

セイ・コンサルティング・グループの新人エンジニア研修のメニューへのリンク

投稿者プロフィール

山崎講師
山崎講師代表取締役
セイ・コンサルティング・グループ株式会社代表取締役。
岐阜県出身。
2000年創業、2004年会社設立。
IT企業向け人材育成研修歴業界歴20年以上。
すべての無駄を省いた費用対効果の高い「筋肉質」な研修を提供します!
この記事に間違い等ありましたらぜひお知らせください。