内部関数を作成する3つの一般的な理由を見てみましょう。
1.閉鎖と工場機能
変数がスコープ外になったり、関数自体が現在の名前空間から削除されたりしても、囲んでいるスコープの値は記憶されます。
def print_msg(msg):
"""This is the outer enclosing function"""
def printer():
"""This is the nested function"""
print(msg)
return printer # this got changed
それでは、この関数を呼び出してみましょう。
>>> another = print_msg("Hello")
>>> another()
Hello
それは珍しいことです。print_msg()
関数は文字列で呼び出され、返された"Hello"
関数は名前にバインドされましたanother
。を呼び出すと、関数another()
の実行はすでに終了していますが、メッセージはまだ記憶されていprint_msg()
ます。一部のデータ("Hello"
)をコードに添付するこの手法は、Pythonではクロージャと呼ばれます。
クロージャを使用するのはいつですか?
では、クロージャは何に適しているのでしょうか?クロージャは、グローバル値の使用を回避し、何らかの形式のデータ隠蔽を提供します。また、問題に対するオブジェクト指向のソリューションを提供することもできます。クラスに実装するメソッドが少ない場合(ほとんどの場合1つのメソッド)、クロージャーは代替のより洗練されたソリューションを提供できます。参照
2.カプセル化:
カプセル化の一般的な概念は、内側の世界を外側の世界から隠して保護することです。ここでは、内側の関数は外側の関数の内側でのみアクセスでき、関数の外側で発生することから保護されます。
3.それを乾かしてください
おそらく、同じコードのチャンクを多数の場所で実行する巨大な関数があります。たとえば、ファイルを処理する関数を作成し、開いているファイルオブジェクトまたはファイル名のいずれかを受け入れたいとします。
def process(file_name):
def do_stuff(file_process):
for line in file_process:
print(line)
if isinstance(file_name, str):
with open(file_name, 'r') as f:
do_stuff(f)
else:
do_stuff(file_name)
詳細については、このブログを参照してください。