だぶるばいせっぷす 新館

ホワイトカラーではないブルーカラーからの視点

【プログラミング】 python奮闘記 その5 ~関数

前回は、条件分岐であるif文と、それに付随するインデントの話を書きました。
インデントとは、半角スペース4回押し、または、tabボタンを1回押すことで文字の書き始めに空間を開ける『アレ』の事です。
kimniy8.hatenablog.com
このインデントは、if文だけではなく、pythonの文法では基本中の基本っぽいので、確実に覚えておきましょう。
プログラムをまとめる時は、文末に『:』を付けて改行し、文頭に半角スペース4つかtabボタンで空白です。

このインデントは、関数と呼ばれるものにも使われます。
関数とは何なのかというのを詳しく説明するだけの知識は私にはまだないので、私やこのブログを読まれている水準の方の理解としては、一まとまりの計算式として覚えて置く程度で良いと思います。
言い方を変えれば、長ったらしい計算式に名前がつけられるのが『関数』という認識で良いのでしょう。

関数の定義の仕方としては、『def』を利用します。
文頭で『def』を書いて、関数の名前を書いき、文末を『:』で閉めて改行します。
当然ですが、改行をした次の行からはインデントを忘れないようにしましょう。

def 関数名:
  処理1
  処理2

この関数ですが、この中では単純な計算式を書いても、if文の様な条件分枝を書いても変数を定義しても良いです。
つまり、今まで勉強した事を全て使えるということです。
言い換えれば、この『関数』自体が小さなプログラムのようなもので、この関数を組み合わせることで、大きなプログラムが完成するという事。

ただ、ひとつだけ注意が必要なのは、『変数』です。
このブログでは、『プログラムでは変数の理解が重要』と度々書いていますが、関数の登場によって、変数への理解がより重要になってきます。
どの様な理解が必要になるのかというと、関数の外と内側、どちらで変数が定義されているのかというのが、とても重要になってくるんです。

関数の外で定義されている変数は、グローバル変数と呼ばれ、関数内で定義された変数は、ローカル変数と呼ばれます。
両者の違いとしては、グローバル変数は何処からでも呼び出せるのに対し、ローカル変数は関数内で完結します。
また、グローバル変数は 『global』という宣言をしない限り、関数内からは代入して数値を変えることが出来ません。

そして、ここからが重要なのですが、変数は基本的にはローカルで定義し、グローバル変数は極力使わないようにします。
ここで、『何故?』と疑問に持たれる方も多いと思います。私もそうでした。

だって、どう考えても、グローバル変数の方が便利じゃないですか。
一度書くだけで、どこからでもアクセスできるんだから、同じ様な数値をイチイチ関数内に書いたり、関数内の変数に代入するなんて事をしなくても良い。
こんな便利な変数を、何故、使ってはいけないのでしょうか。

答えとしては、グローバル変数を使ったプログラムの場合、後々重大なエラーを引き起こしてしまう可能性が高まるからなんです。
例えば、物凄く簡単で短いプログラムを書く場合は、グローバル変数が問題を起こすなんてことはありませんし、仮に問題を起こしたとしても、そのエラーを見つけるのは簡単です。
だから、グローバル変数やローカル変数を区別する重要性は無いのですが、これが、大規模なプログラムになった場合はどうでしょう。

プログラム内で扱っている関数の数も多くなってきて、それらを全て覚えきれないような量にまで膨れ上がった場合、どの関数がグローバル変数に関連しているのかというのが分からなくなってきます。
『自分は記憶力高いから大丈夫!』という方もいらっしゃるかも知れませんが、一人のプログラマーが作っているのではなく、複数人で作っている場合を想定してみてください。
誰が、どんな関数を作っているのかもわからないし、下手をすれば関数内から『global』宣言をして、グローバル変数に別の数値を代入する輩が出てくるかも知れない。

もしそんな身勝手な人が現れれば、グローバル変数を直接読み込んでいる他の関数が有った場合、その関数が答えとして出す値そのものが変わってきてしまいます。
そういうのを避ける為に、変数は基本的には関数内で完結するローカル変数を使うのが暗黙の了解となっているようです。

話を関数の方に戻しましょう。
関数というのは一連の処理をまとめたものなので、同じような処理をコンピューターにもう一度やらせるといった場合に、本領を発揮します。
つまり、普通に書くと物凄く長ったらしいコードになる可能性があるプログラムでも、共通部分をまとめて関数としておけば、書く量を大幅に減らせるという事です。
一度、関数を定義してしまえば、次からは 関数名()と書くだけで実行出来ますし、プログラムに不具合が出て治す場合も、関数を治すだけで大丈夫。
仮に関数が無い場合を考えると、同じ様なコードを何回も書かされるという面倒くさい状況になりますし、修正する場合は、何箇所も同じ修正を繰り返さなきゃいけませんが、その手間をなくしてくれるのが関数です。

つまりプログラムとは、変数を関数によって変化させて、思い通りの動作を可能にするものといえば良いのかもしれません。

何かに例えた方が分かりやすいと思うので、プログラムを車に例えましょう。
車というのは、細かい部品が数多く合わさって出来ていて、素人がパッと見て構造を理解できるものではありません。
ただ、車が動く原因をドンドンと遡っていくと、燃料の爆発まで遡ることが可能で、これをひとつひとつ追っていけば、実は単純な動作の繰り返しだったりします。

車のエンジン内で爆発した燃料は、ピストンという関数によって上下運動を経て、回転運動に変えられます。
エンジンによって回転運動に変えられたエネルギーは、様々な形の歯車によって、そのエネルギーの方向性を変えて伝えられていき、最終的にはタイヤの回転運動に変わります。
タイヤに到達するまでに数多くの歯車によって方向を変えられるわけですが、この、方向を変えられるエネルギーが『変数』で、方向を変える歯車が『関数』という理解でいいと思います。

この、車の流れに乗って、もう一つ上の説明をすると、関数にはその上の存在として、クラスというのが存在します。
このクラスを利用する事で、複数の関数の共通部分をまとめ上げる事も可能っぽいです。
例えば、歯車というのは『回転する』という共通の働きがあります。 なら、その『回転』だけを取り出して、その動きをクラスとして定義してしまえば、それぞれの歯車が持つ『回転』に関する項目はまとめられるという事。
また、クラス内で変数を定義することによって、グローバル変数使わずに、複数の関数間で変数を利用することも可能になります。

この様な構造をみていくと、良いプログラマーとは、共通している部分を如何にして見つけ出し、それらをまとめ上げることが出来るのかという事なんだろうと思います。
共通項を見つけられれば見つけられる程、書くコードの量はドンドン削減されていく事になりますし、結果として早くプログラムを組むことが可能になる。
コード自体が短ければ短い程、読むのに時間がかかりませんし、シンプルであるが故に、エラーが出た時に手直しするのが楽。

ただ、これって、文章で書くのは簡単なんですが、実践するのは非常に難しいような気もするんですよね。
でも、最終的にはその境地を目指す方向で頑張らなくてはならないんでしょうけれどもね。

という事で、ざっくりとした説明だけになりましたが、関数の話はこれで終わりで、次回はモジュールの話をしていこうと思います。
kimniy8.hatenablog.com