カテゴリ: Python 更新日: 2025/12/09

Pythonのクロージャー(Closure)とは?関数内関数とnonlocalの活用

Pythonのクロージャー(Closure)とは?関数内関数とnonlocalの活用
Pythonのクロージャー(Closure)とは?関数内関数とnonlocalの活用

先生と生徒の会話形式で理解しよう

生徒

「Pythonで関数の中に関数を書けるって聞いたんですが、それって何のために使うんですか?」

先生

「それは『関数内関数』というもので、特定の処理を閉じ込めるときに便利です。そして、ある条件で『クロージャー』として活用できます。」

生徒

「クロージャーって何ですか?聞き慣れない言葉です。」

先生

「クロージャーとは、関数内で作った関数が、その外側の変数を覚えて使える仕組みのことです。これを使うと、変数を保ったまま関数を呼び出せます。」

生徒

「じゃあ、普通の変数とは何が違うんですか?」

先生

「そこはnonlocalというキーワードも関わってきます。具体的に説明しましょう。」

-

1. クロージャー(Closure)とは?

1. クロージャー(Closure)とは?
1. クロージャー(Closure)とは?

Pythonのクロージャーとは、関数内で定義された関数が、外側の関数の変数を覚えて使える仕組みのことです。これにより、外側の関数が終了しても、その変数を保持したまま使えます。

例えば、カウンター機能を作るときに、クロージャーを使うとシンプルに書けます。

2. 関数内関数の基本

2. 関数内関数の基本
2. 関数内関数の基本

まずは関数の中に関数を書く例を見てみましょう。


def outer():
    def inner():
        print("これは内側の関数です")
    inner()

outer()

これは内側の関数です

このように、outer関数の中でinner関数を定義し、その中で処理を行えます。

3. クロージャーを使った変数の保持

3. クロージャーを使った変数の保持
3. クロージャーを使った変数の保持

クロージャーを使うと、外側の関数の変数を覚えて利用できます。


def make_counter():
    count = 0
    def counter():
        nonlocal count
        count += 1
        return count
    return counter

c = make_counter()
print(c())
print(c())
print(c())

1
2
3

make_counterが実行されるとcountという変数が作られますが、counter関数がそれを覚えているため、何度呼び出しても前回の値からカウントアップします。

4. nonlocalキーワードの役割

4. nonlocalキーワードの役割
4. nonlocalキーワードの役割

通常、関数の中で変数を書き換えると、それはローカル変数として扱われます。しかし、外側の関数の変数を変更したいときnonlocalキーワードを使います。

上記の例で、nonlocal countを使わないと、エラーや意図しない動作になります。

-

5. クロージャーの活用例

5. クロージャーの活用例
5. クロージャーの活用例
  • カウンター機能:前回の値を保持したまま呼び出せる
  • 設定値の保持:外部から直接変更されたくない値を安全に管理
  • 関数のカスタマイズ:生成時に渡した値を内部で使い続ける

例えば、特定の倍率で計算する関数を作ることもできます。


def multiplier(factor):
    def multiply(number):
        return number * factor
    return multiply

double = multiplier(2)
print(double(5))  # 10

10

6. クロージャーを使うときの注意点

6. クロージャーを使うときの注意点
6. クロージャーを使うときの注意点
  • 変数の保持は便利ですが、意図しない値の変更に注意
  • 複雑な処理になる場合はクラスを使う方がわかりやすい
  • nonlocalは外側関数のスコープにしか作用しない

クロージャーは小規模なデータ保持や設定値の管理に向いています。クラスほど大げさにしたくない場合に特に役立ちます。

まとめ

まとめ
まとめ

クロージャーの仕組みと関数内関数の理解を深めるまとめ

Pythonのクロージャーや関数内関数は、ふだんのプログラミングでは少しむずかしく見える概念ですが、ひとつひとつの特徴をていねいに見ていくと、なぜ便利なのかが自然に理解できます。まず、関数の中に関数を書くという考え方は、処理をひとまとまりにして整理するうえでとても役立ちます。特定の機能を外部から隠しながら内部だけで利用したいときや、外側の値に依存した小さな処理をまとめたいとき、関数内関数は自然な形で使えます。これにより、プログラム全体の見通しがよくなり、必要な部分だけを安全に扱うことができます。

そして、クロージャーとは、この関数内関数が「外側の変数を覚えたまま動く」という仕組みのことです。Pythonでは、外側の関数が終わった後でも、その関数の中にあった変数を保持しつづけられるため、特定の状態を記録しながら処理を続けたい場面でとても強力です。たとえば、繰り返し呼び出すごとに値が変わるカウンターなどは、クロージャーを使うことでクラスを作らずに簡潔に書くことができます。外側の値が毎回保持されるため、前回の結果を踏まえながら計算したい場面では特に役に立ちます。

また、クロージャーを扱ううえで欠かせないのがnonlocalというキーワードです。Pythonでは、関数の中で変数を変更すると、その変数は通常はローカル変数として扱われます。しかし、外側の関数の変数を変更したいときはnonlocalを宣言する必要があります。このしくみにより、外側のスコープの変数を書き換えることができ、クロージャーの動作を正しく成立させることができます。もしnonlocalを使わずに書いた場合、意図しないエラーが起きたり、期待した動作にならなかったりするため、クロージャーを扱う際には必ず押さえておきたいポイントです。

クロージャーは、ちょっとした設定値の保持や、関数の動作を部分的にカスタマイズしたい場面にも向いています。たとえば、特定の倍率で計算する関数を作りたいとき、クロージャーを使えば外側で受け取った倍率を内側の関数が覚え続けてくれるため、いつ呼び出しても同じ計算ルールで処理できます。これは、処理の内容を固定しつつも、コードの見通しを保ちながら柔軟に操作できる大きな利点です。

さらに、プログラムを安全に整理したいときにもクロージャーは役立ちます。外から勝手に触られたくない値を守りつつ、必要な形だけを利用できるため、設定値の保護や動作の一貫性を保ちたい場面にも活用できます。特に、小規模なデータ管理や簡易的な状態の保持を行いたいときには、クラスを使うほど大げさにしたくない場面でも手早く書けるという点がメリットになります。

クロージャーを理解するためのサンプルコード

ここでは、記事で扱った内容をふりかえりつつ、クロージャーとnonlocalの動きをまとめて確認できるサンプルコードを紹介します。


def create_counter(start):
    count = start
    def increment():
        nonlocal count
        count += 1
        return count
    return increment

counter_a = create_counter(5)
print(counter_a())
print(counter_a())
print(counter_a())

counter_b = create_counter(10)
print(counter_b())
print(counter_b())

このコードでは、最初の値を外側の関数で設定し、その値を内側の関数が覚えて使い続ける形になっています。それぞれのカウンターは独立して動き、counter_acounter_bの値が混ざることはありません。これは、クロージャーが外側のスコープをしっかり保持しているからこそ実現できる動作です。状態が必要な処理を簡潔にまとめたいとき、クロージャーはとても実用的な仕組みとして役立ちます。

ただし、クロージャーは便利な反面、複雑なロジックを詰め込みすぎると、どの変数がどこで使われているのかがわかりにくくなる場合があります。そのため、大規模な処理や複雑な状態を扱いたい場合には、クラスを使う方がより適切なこともあります。用途に応じてクロージャーとクラスを使い分けることで、プログラム全体の見通しがよくなり、保守性も高まります。

クロージャーの仕組みを理解しておくことで、Pythonの関数の奥深さをより深く知ることができ、プログラミングの応用範囲が大きく広がります。外側の値を覚えたまま処理を続けるという特徴は、実践的な場面でも多く利用されるため、この機会にしっかり身につけておくと、今後の学習にも大いに役立つでしょう。

先生と生徒の振り返り会話

生徒「きょうのクロージャーの話で、関数が外側の変数を覚えているというところがすごく印象に残りました。意外と簡単に使えるんですね。」

先生「そうですね。仕組みを知るととても便利ですし、状態を持った関数を作りたいときに役立ちます。カウンターの例は典型的で、覚えておくといろんな場面で応用できますよ。」

生徒nonlocalが必要な理由もやっと理解できました。あれがないと外側の変数が変わらないんですね。」

先生「その通りです。Pythonのスコープの仕組みと合わせて覚えておくと安心です。困ったときは、『外側の変数を変えたいならnonlocal』と考えるとわかりやすいですよ。」

生徒「ありがとうございます。クロージャーってむずかしいものだと思っていましたが、今日の例を見てだいぶ理解できました。これからもっと使いこなしてみます!」

先生「とても良い姿勢ですね。実際にコードを書きながら試すことで、さらに理解が深まりますよ。」

この記事を読んだ人からの質問

この記事を読んだ人からの質問
この記事を読んだ人からの質問

プログラミング初心者からのよくある疑問/質問を解決します

Pythonのクロージャーとは何ですか?初心者向けに簡単に教えてください

Pythonのクロージャーとは、関数の中で定義された関数が、外側の関数の変数を覚えていて、後からでもその値を使える仕組みのことです。特定の状態を保持した関数を作るときに便利です。
コメント
コメント投稿は、ログインしてください

まだ口コミはありません。

カテゴリの一覧へ
新着記事
New1
PHP
PHP のフォームデータの受け取り($_POST, $_GET)を完全解説!初心者向けガイド
New2
PHP
PHPのスコープとは?グローバル・ローカル・スーパーグローバルを完全解説!
New3
PHP
PHPの演算子をやさしく解説!算術・比較・論理・ビット演算子の使い方
New4
PHP
PHP の変数とは?基本的な使い方とデータ型を徹底解説!
-
人気記事
No.1
Java&Spring記事人気No1
Python
Pythonで辞書のキー・値・アイテムを取得する方法(keys(), values())
No.2
Java&Spring記事人気No2
Python
Pythonで辞書のネスト構造(入れ子辞書)を扱う方法 初心者向け完全ガイド
No.3
Java&Spring記事人気No3
Python
Pythonでエラースタックトレースを表示・取得する方法を徹底解説!初心者向け例外処理入門
No.4
Java&Spring記事人気No4
Python
PythonでMySQLに接続する方法を完全解説!初心者でもわかるpymysqlの基本
No.5
Java&Spring記事人気No5
Python
PythonでExcelファイル(.xlsx)を操作する方法を徹底解説!初心者でもできるopenpyxl・pandasの使い方
No.6
Java&Spring記事人気No6
PHP
PHPで画像ファイルをアップロードする方法を初心者向けに徹底解説!わかりやすい画像処理入門
No.7
Java&Spring記事人気No7
PHP
PHP のデータ型を完全ガイド!初心者でもわかる int, string, float, bool など
No.8
Java&Spring記事人気No8
PHP
PHP の日付と時間の取得(date, time, strtotime)を完全解説!初心者でもわかる使い方
-
-