Python の入れ子関数

Manav Narula 2023年10月10日
Python の入れ子関数

関数は、プログラムで何度も呼び出すことができるコードのブロックです。さまざまな引数を受け入れることができ、いくつかの有用な値を返すことができます。すべてのプログラミング言語には、組み込み関数とユーザー定義関数があります。

このチュートリアルでは、Python でネストされた関数を作成して使用する方法を学習します。

ほとんどの言語は、ネストされた関数の使用と作成をサポートしています。名前が示すように、入れ子関数は関数内の関数です。内部にネストされた関数は内部関数と呼ばれ、囲んでいる関数は外部関数と呼ばれます。

次のコードでは、基本的な入れ子関数を作成します。

def outer_f(s):
    def inner_f(s):
        print(s)

    inner_f(s)


outer_f("Nested")

出力:

Nested

上記の例を使用すると、ネストされた関数の使用について少し理解できます。これらは、関数を外界から隠し、データのカプセル化を実装するために使用できます。

知っておくべきもう 1つのことは、入れ子関数は外部関数で使用される変数を使用できるということです。このような変数は非ローカルと呼ばれます。ネストされた関数はそれらにアクセスできますが、それらを変更する必要がある場合は、nonlocal キーワードを使用する必要があります。

次の例を見てみましょう。

def outer_f():
    s = 5

    def inner_f():
        nonlocal s
        s = s + 1
        return s

    return inner_f()


print(outer_f())

出力:

6

ここでは、nonlocal キーワードを使用せずに s 変数を変更することはできません。

ここで、ネストされた関数が何らかの値を返すかどうかを想像してみてください。これにより、ネストされた関数のもう 1つの便利な機能であるクロージャ関数が得られます。これらの関数は、ネストされた関数を使用して動的に作成されます。これは、データ隠蔽を実装し、クラスの代替として使用するためのエレガントで簡潔な方法かもしれません。

次のコードを参照してください。

def incrementer(x):
    def inc(y):
        return x + y

    return inc


by4 = incrementer(4)
by5 = incrementer(5)

print(by4(5), by5(5))

出力:

9 10

上記のコードでは、数値をインクリメントする動的メソッドを作成します。by4by5 は、入れ子関数を使用して作成された 2つのクロージャ関数です。これは主に、ネストされた関数がその状態を保持できるためです。関係する属性が多すぎない場合は、クラスやグローバル変数の適切な代替手段になる可能性があります。__closure__ 属性を使用して、関数がクロージャであるかどうかを確認できます。すべての関数にはこの属性があり、クロージャ関数と一緒に使用するといくつかのセルオブジェクトが返されます。

ネストされた関数は、デコレータ関数にも使用されます。デコレータ関数は、クラス、関数などの呼び出し可能なオブジェクトを使用し、別のオブジェクトを返します。このような呼び出し可能なオブジェクトの前にデコレータを使用するには、@記号を使用します。このように、呼び出し可能なオブジェクトをデコレータ関数の引数として受け取り、それを使用します。

次の例では、これをよりよく理解するために、非常に単純なデコレータ関数を作成します。

def dec(func):
    def inner():
        print("Hello")
        func()

    return inner


@dec
def world():
    print("world")


world()

出力:

Hello
world

上記の例では、dec() と呼ばれる単純なデコレータ関数を作成しました。この関数は、world() 関数を引数として使用し、追加のメッセージを出力することで装飾します。

著者: Manav Narula
Manav Narula avatar Manav Narula avatar

Manav is a IT Professional who has a lot of experience as a core developer in many live projects. He is an avid learner who enjoys learning new things and sharing his findings whenever possible.

LinkedIn

関連記事 - Python Function