関数について学んでいきましょう。
関数は、一連のコードの集まり(ブロック)のことを言います。
ブロックのイメージがわかない方は、ブロックという記事を参考にして下さい。
メモリで関数実行のイメージをふくらませる
関数実行の具体的なイメージを、メモリを使ってみていきましょう。
なお、メモリについて理解を深めたい方は、メモリとアドレスという記事を参考にして下さい。
メモリといっても、伝えたいことは「上から順番にコードが実行されていく」ということですので、その点だけ意識すると良いかと思います。
まずは、イメージで関数がどのように実行されるかを見ていきましょう。
関数Aに関するコードが、6番地からx番地にかけてメモリの中に格納されています。
他方、コードは上から実行されますので、まずは1番地のコードが実行されます。
2番地には、A関数が格納されている6番地の参照情報が書き込まれていますので、6番地にジャンプします。
6番地にジャンプした後は、関数のブロックが順番に実行されていきます。
x番地にはreturnが入っています。このreturnは、関数を呼び出した番地に戻すという意味です。
結果として、関数が呼びされた1番地に戻り、2番地・3番地のコードが順に実行されていく。というイメージです。
実際のコードで確認してみましょう。
このようなコードがあったとします。
コード1 def animal():
2 print('hello')
3 return
4 a = 10
5 b = 20
6 animal()
7 c = 30
コードの解説(1) 1行目で、animalという名前で関数を定義しています。関数はインデントによって範囲(ブロック)が決められます。今回の例では1行目から3行目までがブロックです。つまり、1から3行目までの関数情報がメモリに格納されます。
その際、変数と番地を結びつけるようなイメージで、関数名(ここではanimal)と番地(ここでは6番地とします)を関連づけておきます。
(2) 4行目からコードが実行されていきます(3行目まではブロックなので)。
4行目のコードが実行されると、変数aに10が代入されます。次に、5行目のコードが実行され、変数bに20が代入されます。
(3) 6行目で、animal関数を呼び出していますので、1行目から3行目までのコードが順番に実行されていきます。
(4) 3行目のreturnは呼び出し元に戻るという意味ですので、4行目に戻り、また順番にコードが実行されていく。という流れです。
関数を使うメリット
関数の具体例をみてきました。
ここからは、関数を使うことのメリットについて学んでいきましょう。
ちなみに、言語が備えているメリットからプログラミングを学ぶというのは非常に大切な考え方です。詳しくは、Python(プログラミング)の勉強をする前におさえておくべきポイントという記事で詳しく説明しています。
複数の処理を一度に実行できる
関数を使うことによって、複数のコードを簡単に使い回すことができるようになります。
複雑なプログラムの場合、一つの処理で数百行という長さのコードになることも珍しくありません。
そういった場合に、一回一回数百行のコードを書いて実行するのはあまりにも非効率です。
関数のおかげで、多くの処理を簡単にまとめることができるのです。
メモリの使用量をへらすことができる
同じコードを何回も書いてそれをメモリに書き込んでいくのは、メモリの無駄使いです。
関数を使うことによって、メモリの使用量を減らすことができるのです。
関数の書き方(def, : , インデント)
次に、Pythonでの関数の書き方について学んでいきましょう。
def
関数を宣言するためには、defという言葉を使います。
関数の名前の前にdefをつけることによって、これは関数だということをPythonに理解させることができるのです。
:
次はコロンです。関数名を示した後にはコロンを付けることがルールとされています。
なぜコンマをつけるのかということについて明確な理由は無いようですが、コロンがあった方がコードが読みやすいということが理由のようです。
例えば、以下の2つのコードがあった場合、どちらが読みやすいでしょうか?
コードif a < b :
print(a)
コードif a < b
print(a)
ここではあえてインデントをスペース一つにしていますが、Pythonの文法上は正しい書き方です。(推奨される書き方ではありません。)
この時、上のコードではコロンがあるので、このif文の後から関連するコード(ブロック)があることがはっきりわかりますが、下の例では、パッとみた感じではどこからブロックが始まっているのか分かりませんね。
インデント
最後はインデントです。
Pythonでは、インデントを使って関数の対象となる範囲(ブロック)を示します
他の言語では{}などを使ってブロックの範囲を明示していましたが、インデントの方がすっきりする、というのがPythonがインデントを採用した理由のようです。
関数の理解をさらに深める
関数への理解をさらに深める上で、押さえておいた方が良いポイントについて見ていきましょう。
カッコ()を付けない場合は、関数は実行されず、関数の場所を参照する
関数は、かっこがついた時に実行され、かっこがついていない場合は関数の場所を参照します。
実際にコードを見て確認してみましょう。
コード1 def sample():
2 return
3 print(sample)
アウトプット<function sample at 0x7f8f045e12>
3行目のprint関数に注目して下さい。ここでは、sample()ではなくsampleとしています。
結果のコードは、<function sample...>という内容になりました。これは関数そのものを示しており、関数を実行していないということです。
違う例で考えてみましょう。例えば、sample.pyというファイルがあったとします。このファイルを実行すると(ファイルにかかれているコードを実行すると)、実行結果が表示されます。
その一方、ファイルを実行せずに、ファイル名をそのまま使うときもありますよね。
関数も同じようなイメージです。呼び出して実行する場合と、関数そのものを示す場合があることを意識しましょう。
関数を引数に取ることもできる
また、関数を引数に取ることもできます。
これは非常にイメージがわきづらいです。
ですので、コードを見ながら、関数も引数に取れるということについて何となくイメージがわけばよいかと思います。
具体的なコードを見ていきましょう。
コード1 def sample(argument):
2 return argument
3 def func():
4 return
5 a = sample(func)
6 print(a)
アウトプット<function func at ....>
コードの解説(1) 5行目から見ていきます。5行目でsample関数を実行し、funcを引数としています。
(2) sample関数が実行されますので、1行目のsampleが実行されます。この関数は引数argumentを返しますが、今回はfuncが引数ですので、funcが返されます。
(3) 6行目で変数aを出力していますが、aには関数funcが入っていますので、出力結果は関数を参照することになります。
関数もしっかりと引数として使うことができました。
関数のまとめ
(1) 関数は実行するコードをまとめたもの
(2) かっこが付くと関数が実行される
(3) 関数を引数に取ることもできる
関数を学んだあとは
関数とは切っても切れない関係である変数について学んでいきましょう。