Pythonの関数の引数に他の関数を渡して使う方法について

イメージ画像


Pythonでは関数の引数に他の関数を渡すことができます。


関数を受け取った関数は、関数(自身)の中で受け取った関数を使うことができます。この説明だけだと何のことかよく分からないと思うので、早速簡単なプログラムを見てみることにします。 

引数で受け取った関数を関数内で使ってみる


def calc(func, num=1):
    cost = func(num)
    return cost
    
def apple_cost(num):
    return 100 * num

num = 3 #①
total_cost = calc(apple_cost, num) #②
msg = '購入金額は{}円です。'.format(total_cost)
print(msg)



これは、りんご1個の値段を100円として、りんごを何個か買った時の購入金額を計算するプログラムです。

初めに関数calc()を定義しています。
関数calc()は、引数に関数(func)と数値(num、りんごの個数)を受け取り、numを引数としてfunc()を実行し、その戻り値がcostになります。

次に関数apple_cost()を定義しています。
関数apple_cost()は、受け取った引数num(りんごの個数)に100(りんご1個の値段)をかけた値(購入金額)を返します。

それでは、この2つの関数がどのように使われるのかを見ていきましょう。

まず、①でnumに3を代入しています。これは、りんごの購入数です。

②では、関数calc()の戻り値をtotal_costに代入しています。この時、calc()は引数にapple_cost()とnumを取っています。

関数calc()の中では、引数として受け取ったapple_cost()とnumを使ってcostを求めています。apple_cost()は引数の値に100を掛けて返す関数なのでapple_costの戻り値は300になり、calc()内のcostも300になります。

関数calc()はその300を返し、msgには’購入金額は300円です。’という文字列が入ります。

最後にprint()でmsgを表示してプログラムは終了します。

わざわざ関数を2つも用意するまでもないプログラムですね。だけど、関数の引数に関数を取る流れは分かったような気がします。

引数で受け取る関数を増やす

次はこのコードを発展させて、関数calc()がapple_cost()以外の関数も受け取るようにしてみます。


def calc(func, num=1):
    cost = func(num)
    return cost
    
def apple_cost(num):
    return 100 * num
    
def orange_cost(num):
    return 50 * num

apple_num = 3
orange_num = 5
total_cost = calc(apple_cost, apple_num) + calc(orange_cost, orange_num)
msg = '購入金額は{}円です。'.format(total_cost)
print(msg)

今度のプログラムでは、orange_cost()という関数を追加してオレンジの購入金額も計算できるようにしてあります。オレンジ1つの値段は50円ですね。

関数calc()は、引数としてapple_costを受け取った時はリンゴの購入金額、orange_cost()を受け取った時はオレンジの購入金額を計算できるようになりました。

関数calc()自体は何の変更も加えていないのですが、引数で受け取った関数を関数内で使うようにコードを書いていたので、引数で受け取る関数を増やすことで色々な処理ができるようになったのです。

もちろん、リンゴとオレンジの購入金額を計算するプログラムは他に色々な方法があります。ある結果を出すためのプログラムは1つではないからです。そこがプログラミングの難しい所でもあり、楽しい所でもあると思います。

同じ結果を得るコードにしても、コーディングの速さを重視したもの、プログラムの実行スピードを重視したもの、可読性を重視したもの、メンテナンス性を重視したものなど色々なものがあります。

今回の関数の引数で他の引数を受け取る方法や、前回の関数を変数に入れて使う方法は、知らなくてもプログラムを書くことができます。だけど、活用することで可読性やメンテナンス性に優れたプログラムを書くことができるようになります。



プログラミング って本当に奥が深いですね。
これからも勉強を続けて少しでも良いコードが書けるように頑張ります!

0 件のコメント :