Address
304 North Cardinal St.
Dorchester Center, MA 02124

Work Hours
Monday to Friday: 7AM - 7PM
Weekend: 10AM - 5PM

Pythonプログラミング(関数を呼び出す関数)

Pythonで関数から別の関数を呼び出して使う方法について初心者向けの解説。呼び出し元(caller)と呼び出し先(callee)とreturn文について

Pythonプログラミング初心者に向けた、関数の中で別の関数を呼び出して使う方法と、呼び出し元(caller)と呼び出し先(callee)という用語とreturn文についての解説

今回もPython初心者に向けた簡単な文法事項の解説です。今回のネタは関数を呼び出す関数を作って利用する方法の解説です。

「どういうこと?」と思われるでしょうが、理屈は簡単なので安心してください。それは具体的にコードを見ていきましょう。

具体例

まずは次のコードを見てください。

#1 関数fnc_nameの定義・宣言
def fnc_name(a):
    return a #←外にある別の関数fnc_hello(呼び出した側の関数)に値を返す

#2 関数fnc_helloの定義・宣言
def fnc_hello(b):
    name=fnc_name(b) #←外にある関数fnc_nameを実行
    print(f'{name}さん、こんにちは')

#3 関数fnc_helloを実行(引数に文字列"田中"を指定)
fnc_hello("田中")

非常に単純なものなので説明は不要かもしれませんが、ポイントは、ある関数が別の関数を呼び出している点ですね。

すなわち、#2において関数fnc_helloの定義の中で、「その外側で定義・宣言されたfnc_name」を実行して利用している点です。

「呼び出し元」と「呼び出し先」という用語について

この場合は、

  • fnc_nameは、呼び出された側(呼び出し先、callee、コーリー)
  • fnc_helloは、呼び出した側(呼び出し元、caller、コーラー)

となっています。

呼び出し元と呼び出し先が日本語として混乱してしまいがちですが、「呼び出し=命令という情報」と考えて、

  • 呼び出し元は、命令が出発する地点(スタート)。命令を出す側
  • 呼び出し先は、命令が到達する先(ゴール)。命令される側

という感じでイメージすると良いと思います。

では次にこのコードの動き方を見ていきましょう。

動作・仕組みの解説

再び上のコードをそのまま載せます。

#1 関数fnc_nameの定義・宣言
def fnc_name(a):
    return a #←外にある別の関数fnc_hello(呼び出した側の関数)に値を返す

#2 関数fnc_helloの定義・宣言
def fnc_hello(b):
    name=fnc_name(b) #←外にある関数fnc_nameを実行
    print(f'{name}さん、こんにちは')

#3 関数fnc_helloを実行(引数に文字列"田中"を指定)
fnc_hello("田中")

#3の部分

fnc_hello("田中")

この部分ですが、これは引数に文字列「田中」を指定して、それより上で宣言された関数fnc_helloを実行しているだけです。

#3で指定された引数である文字列「田中」という情報が、fnc_helloの引数のbに入って、b=”田中”となります。

#2の部分

次に、#2の、

#2 関数fnc_helloの定義・宣言
def fnc_hello(b):
    name=fnc_name(b) #←外にある関数fnc_nameを実行
    print(f'{name}さん、こんにちは')

の部分ですが、ここは次のような動作の仕組みとなっています。すなわち、

・すでに、b=”田中” となっている

関数fnc_helloが、その中にある関数fnc_name(b)を呼び出す。すなわち、b=”田中” を使って、「fnc_name(“田中”)へと変われ!そしてそれを実行しろ!」と命令を出す(?)。

#1で定義・宣言された fnc_name(a)の引数aに、”田中”が入っている状態(a=”田中”)になるので、return文によって文字列「田中」が呼び出し元であるfnc_helloへ返され、その結果、name=”田中” となる

print文によって、変数nameの情報をつかってメッセージが出力される

このような流れになっています。

return文について

関数から関数を呼び出す場合に重要なのはreturn文の有無とその役割です。

#1 関数fnc_nameの定義・宣言
def fnc_name(a):
    return a

仮にこの#1の関数の宣言から、return文を削除すると、今回のコードは上手く動きません。

なぜなら、return文は、呼び出し元へデータを返すという働きを担っているからです。もしそれがなければ、呼び出し元であるfnc_helloはそのデータを利用できず、変数nameは中身が定義されないままの状態となるからです。

fnc_name内での処理されたデータは、fnc_name内では利用できますが、その外側で定義された関数fnc_helloでは利用できません。

あくまで定義されたそれぞれの関数ごとにそれぞれのデータが管理されていて、他の関数からは自由に手出しできないようになっているからです。

そこでreturn文によるデータの受け渡しという機能が必要になっているのですね。

関数の中で別の関数を呼び出す方法のメリットとは?

今回の具体例のコードは、まさに勉強のためのコードという感じであって特にそれ自体に意味のあるコードではありません。

実際、今回のような処理ではわざわざ2つの関数を定義する必要はなく単にfnc_helloの中に、直接fnc_nameが担当しているような処理を書けばいいだけです。つまり、

def fnc_hello(x):
    name=x 
    print(f'{name}さん、こんにちは')

fnc_hello("田中")

と書けば済む話です。

しかし、たとえば大雑把ですが次のような構造にする場合、

def 関数A():
    長く複雑な処理

関数A()実行

この場合に、「長く複雑な処理」の部分だけを別の関数(たとえば関数B)として設定しておき、関数Aの定義・宣言とは外側に書いておけば、関数Aの定義・宣言の部分のコードが短くなり、関数Aが見やすくなります。

たとえばこのようにしてみましょう。

def 関数B():
  長く複雑な処理
def 関数A():
    ~

関数A()実行

またその「長く複雑な処理」だけをコードの中で何度も繰り返して使いたくなった場合に、毎回それを繰り返し記述(コピペでも)する必要がなくなり、使いたい場所で、

関数B(引数指定)

と書けば良いだけです。こっちのほうが省エネですよね。

以上のように関数の中で、別の関数を呼び出す方法は、

  • 見やすくなる
  • 省エネ(使いまわししやすくなる)

というメリットがあります。

【今回の記事と関連する記事】

愛を分かち合いましょう