超初心者のための関数(def構文)

 最初は上から下に向かってダラダラコードを書いて動けばよかった。少し慣れてくると関数の存在に気付いて、なんだか出来ない自分が恥ずかしくなってくる。そこで初めて「def 構文」を意識するんじゃないかと思う。ここでは関数が気になってきた超初心者のために「def構文」の基本を押さえてみようと思う。

「def構文」の基本

まずは基本形式を説明する。
 ① 「def構文」の基本形


  • 1行目は「 def 関数名(): 」と書く。関数名は任意につけられる。変数がなくても()は必要。
  • 2行目はTab一個分だけあけてから処理するコードを書く。これは「for文」と同じく「def」に紐づいた処理であることを明示している。
  • 関数を実行するには 関数名() と書けば実行される。

 書いといてなんだけど、こんなコードを書くことは実際はほとんどない。
大抵の場合変数があるし、「return」で処理した結果を取り出すような場合も多い。


 ②「変数」がある場合


  • Functionに変数mが加わった。実行されると「 print(m) 」で出力される。
  • ここでは 「 Function("Hello") 」 で実行されることで m に ”Hello” が代入されることになる。


 変数を入れた形を説明した。さらに実行した結果を取り出して使っていきたい場合はどうしたら良いだろうか?

 ③「変数」 &「return」あり


  • この関数はmを受け取ったら m*2 を「return」で戻す。
  • 戻ったものは変数 reply に代入されている。
  • 「return」がなければ何も戻らないし、「=」で変数に格納しなければ取り出せない。

 以上、基本の形を説明した。最初は慣れない形に戸惑うかもしれないが、使っていけばすぐに慣れると思う。ここではさらに「def構文」を使うことの意義について以下の項目で説明する。

「def構文」 の有無でどのように変わるか

 ①defを用いない場合の適当な計算を示す。

a= 2
b= 3
X= 1
Y= 1
T = a*X + b*Y          # 2*1 + 3*1 = 5
print(T)                    #  5
  • 見ての通り、上記のコードは変数 a, b, X, Y を用いたただの四則演算である。
  • X, Yは数式で言う変数を意識して、a,bは定数を意識しているが、コード上ではすべて変数である。

 
 ②「def構文」を使用した場合

a=2
def Function(X,Y):
    b=3
    T = a*X + b*Y               # 2*1 + 3*1 = 5
    return T

answer = Function(1,1)      #T=5 の 5 がanswer に代入される
print(answer)                 #  5
  • 行数は増えたが、「def 」で四則演算を行う部分が明確になった。
  • 変数 X, Yも(定数を意識した)a, bとは明確に異なる。

 違和感を感じた方もいらっしゃるかと思いますが、上記はやや不自然なコードです。
本来は下のように、aとbを同じ領域に書く方が自然です。

def Function(X,Y):
    a=2
    b=3
    T = a*X + b*Y               # 2*1 + 3*1 = 5
    return T

 なぜ少し不自然な書き方にしたかと言うと、def構文を扱う上では、グローバル変数」と「ローカル変数」の概念を意識して欲しかったからである。これについては次項で説明する。

グローバル変数」と「ローカル変数」

 上記の通りdef構文自体はそこまで複雑ではない。でも実際に動かすとなるとこの概念を押さえておく必要がある。もう一度先ほどのコードを以下に示すが、どれがグローバル変数でどれがローカル変数なのだろうか?

a=2
def Function(X,Y):
    b=3
    T = a*X + b*Y               # 2*1 + 3*1 = 5
    return T

 先に答えを書くと、a がグローバル変数、b がローカル変数となる。一体何が違うのだろうか?ここで一度冒頭で表示した下のイメージ図を見て欲しい。


  • 「def関数」を箱のイメージを持ってもらえれば良い。
  • 箱の外の変数a は「グローバル変数」であり、どこでも呼び出して使うことが出来る。
  • 箱の中の変数b は「ローカル変数」であり、箱の中でしか使用できない。


 ここでこう思った人もいるかもしれない。すべての変数をグローバルに置いておけばどこでも使えるじゃないかと。確かに短いコードでは問題ないが、非常に多くの変数を使うような場合はどうだろうか。全てをグローバルに置いてしまうと、変数の羅列によりその変数がどこで使うものなのか非常に分かりづらくなる。あるいは同じ変数名を使ってしまうと、その変数に対する意図せぬ操作が悪影響してしまう場合もありうる。
 よって、その関数内でしか使わない変数はローカル変数として定義すべきである。

また、ローカル変数が関数の中で使用するために設けられることの裏返しで、そのままではローカル変数をグローバルに呼び出せないということは改めて認識しておいてほしい。例えば上記の例の変数Tはローカル変数であるため外で使うことが出来ない。
答えはすでに書かれているが、計算結果のTを外で使うために、「return」 を用いているのである。

まとめ

 自分が「def構文」に挑戦した時を思い出すと、思ったようにうまく動かなかったり、処理した結果を利用するところで少し混乱していた時があったと思う。総合的な知識不足もあったのだが、一番はグローバル変数とローカル変数に関してあやふやなまま書いていたからである。そんな私を反面教師にして皆さんは最初からバリバリ使いこなしていただければ幸いです。