Pythonの基礎を習得した後にまず覚えておきたいのが関数です。
この記事ではPython初心者向けに関数を分かりやすく解説しております。
関数の必要性
Pythonにおける関数の役割と必要性を解説いたします。
まず、大前提としてPythonは様々な書き方ができる言語です。
実際、関数やクラス等を覚えていなくてもライブラリの操作さえできれば、
例えばスクレイピングで今日の天気を取得してExcelに保存する事や、
csvファイルにまとめたキーワードを元に文章生成し、ブログに投稿する事等、様々な事が行えます。
そう、これらは別に関数を覚えていなくても実装できます。
では、何故関数を扱えるようになりたいのか
そもそもこれまで当たり前のように使用していたprint()
これも関数です。print関数です。
print関数は引数として渡したものを出力する関数となります。
print関数は便利ですよね。そもそもこれがなくては相当不便です。出力する為のコードを自分で毎回記述する必要があります。
他にも要素の数を数えてくれるlen関数も基礎の段階で習得していると思います。
len関数は要素の数やオブジェクトの長さを数えてくれるのでfor文との相性は抜群ですね!
しかし、len関数がなければ、要素の数を数えてくれるコードを毎回記述する必要が出てきます。
つまり関数は便利なのです!
組み込み関数
先ほど述べたprint関数やlen関数はPythonで予め用意されている関数です。
このような関数は組み込み関数と呼ばれます。
ユーザー定義関数
関数は自分で自作する事も可能です。
自作した関数はユーザー定義関数、独自関数、自作関数等、様々な呼ばれ方がありますが、ようはどれも同じです。
関数を作ってみよう
実際に関数を作ってみましょう。
今回は身長と体重を渡してあげる(引数)とBMIが返ってくる(戻り値)関数を自作します。
def bmi_calc(height,weight):
bmi = weight/height/height
return bmi
s = bmi_calc(1.7,69)
print(s)
さて、今回はあえてこのようにBMIを計算する関数を作ったのですが、
上記コードを走らせると結果として23.875432525951556と出力されます。
この段階で少し深堀してみましょう。
まず、一行目のdef bmi_calc(height,weight):ですが
関数はdef 関数名(引数1、引数2):と記述します。
今回はBMIを計算する関数なので、関数名はbmi_calcとしています。
少し脱線しますが関数名は半角小文字で必要に応じて単語をアンダーバーで区切ります。
これはPythonの標準ライブラリ等で使用されているPEP8のコードの命名規則に沿ったものとなります。
PEP8はPythonを作成したグイド・ヴァンロッサム氏のエッセイを元にして作成されておりますので、
関数名を小文字+アンダーバーとすることは広く一般的なルールとして用いられています。
話を戻して関数名の後ろには半角の括弧を用意して、中には引数を予め指定しておきます。最後の:はfor文等と同じですね。
今回の引数は(height,weight)つまり身長と体重を予め指定してます。
引数はいくつでも指定する事ができます。
引数を指定する方法はいくつかあるのですが、特に多く用いられるのが上記のようにキーワードをカンマ区切りで用意する方法となります。
これを位置引数と言います。
他にもキーワード引数等もありますが、この記事では位置引数で統一しておりますので、気になったらpython 引数等で検索して下さい。
2行目のbmi = weight/height/heightは関数の処理を記述しています。
今回はBMIを計算しますので体重を身長の2乗で割っています。
それをbmiという変数に格納しています。
さて、ここでbmiという変数にBMIが格納されているならコードの最後はprint(bmi)でよくない??と思われた方もいるのではないでしょうか。
実際にコードのprint(s)をprint(bmi)に置き換えて実行してみましょう。
すると
NameError: name ‘bmi’ is not defined
bmiという変数は存在しないとエラーが発生してしまいました。
関数の中で定義された変数はローカル変数と呼ばれ、関数の中でしか機能する事ができません。
この範囲をローカルスコープと呼びます。
ローカルスコープ内ではローカル変数が使えますので3行目のreturn文の前にprint(bmi)を挿入して実行してみましょう。
def bmi_calc(height,weight):
bmi = weight/height/height
print(bmi)
return bmi
s = bmi_calc(1.7,69)
print(s)
すると
23.875432525951556
23.875432525951556
とbmiが2回出力されています。
さて、ローカルスコープ内でしかbmiの変数を使えないなら、bmiの計算結果をどのようにしてローカルスコープの外に出してあげればいいのでしょうか。
答えはreturn文です。
return文は関数で処理された内容の結果を戻り値として指定する事が出来ます。
今回はreturn bmiと変数bmiの値をbmi_calc関数の戻り値としています。
return
returnについては少し深堀して理解する必要があります。
関数にはreturn文が必要のない関数もあります。
def hello(name):
print("こんにちは",name)
hello("太郎")
例えば、上記のようなコードではローカルスコープ内でprintで出力しているのでreturn文は必要ありません。
return文がない時は関数の戻り値はNoneとなります。
実例を見てみましょう。
def hello(name):
print("こんにちは",name)
s = hello("太郎")
print(s)
上記の結果は
こんにちは 太郎
None
となり変数sの中身はNoneであることが分かります。
return文が実行されたタイミングで関数の処理は終了します。
例えば
def bmi_calc(height,weight):
bmi = weight/height/height
return bmi
print("ここは処理されません")
s = bmi_calc(1.7,69)
print(s)
上記のように記述してもreturn文の後のprint関数は処理されません。(そもそもエラーで実行できません。)
return文は関数を終了させる場合に用いる場合もあります。
例えばfor文の処理を終わらせたい場合等にbreak文の代わりとしても使えます。
def hello():
persons = ['太郎', 'よし子']
for person in persons:
print('こんにちは',person)
return
hello()
このコードの出力結果は
こんにちは 太郎
となり、for文内の処理でreturn文が実行されたため関数の処理が終了し、こんにちはよし子と出力されません。
また、関数の結果をNoneとして後に使用したい場合は
retrun None
と記述したほうが可読性が向上すると思われます。
関数の呼び出し
関数の呼び出しは
関数名(引数)
で行います。先ほどのコード5行目は
def bmi_calc(height,weight):
bmi = weight/height/height
print("関数は実行されています。")
return bmi
s = bmi_calc(1.7,69)
上記コードで”関数は実行されています。”と出力されている事からも関数を呼び出して処理されている事が分かります。
また、関数は別ファイルからも呼び出すことが出来ます。
今回はmyclac.pyというファイルを作成し、先ほどの関数を入れておきます。
同じ階層内で別ファイルを作成し、myclac.pyからbmi_calc関数を呼び出します。
import mycalc
mc = mycalc.bmi_calc(1.7,70)
print(mc)
上記コードでBMIが出力されます。
この時、関数が入っているファイル側をモジュールと呼び、実行する側のファイルをスクリプトと呼びます。
モジュールには複数の関数を入れる事も出来ます。
よく使う関数は纏めておくと便利ですね。
関数を外部ファイルから呼び出す際の書き方は幾つかあります。
先ほどの書き方は
import モジュール名
モジュール名.関数名(引数)
となっていますね。
スクリプト側でモジュール名を省略する事も出来ます。
from mycalc import bmi_calc
mc = bmi_calc(1.7,70)
print(mc)
from モジュール名 import 関数名
とする事でモジュール名を省略して関数を実行できます。
また
import モジュール名 as 別名
とすることでモジュール名を別名として扱う事もできます。
import mycalc as mc
mc.bmi_calc(1.7,70)
if __name__ == “__main__”:
関数に関しては凡そ理解していただけましたでしょうか。
これから更に関数への理解を深める為に他のサイトや書籍にて関数を勉強していくことになるかと思います。
そこで必ず初心者がぶち当たるのが
if __name__ ==” __main_”_:
という記述です。
ここではざっくりと解説をします。
そもそも__name__とはなんでしょうか。
このようにclass内の関数に__を前後につけたものを特殊メソッドと呼びます。
関数とメソッドの違いについてざっくり説明すると
関数は関数。class内の関数はメソッドになります。
では__name__の正体をprintで出力して確認してみましょう。
__main__と表示されます。__name__は現在のモジュール名を示します。
つまり、if __name__ ==” __main_”_:より配下に記述されたコードは
モジュール自身を呼び出した際に行われます。
例を用いて見ていきましょう。
先ほど作成したmycalc.pyの中身をこのようにします。
def bmi_calc(height,weight):
bmi = weight/height/height
return bmi
print("これはBMIを計算する為の関数が入っているモジュールです。")
これをメインスクリプトで呼び出して先ほどと同じようにBMIを出力してみましょう。
import mycalc
mc = mycalc.bmi_calc(1.7,70)
print(mc)
すると
これはBMIを計算する為の関数が入っているモジュールです。
24.221453287197235
とモジュールのprint文が出力されてしまいました。
これは関数を呼び出したことによりprint文が実行されたわけではなく、importした段階でmyclac.pyが実行されている為です。
これでは困りますのでmyclac.pyをこのように変更します。
def bmi_calc(height,weight):
bmi = weight/height/height
return bmi
if __name__ == "__main__":
print("これはBMIを計算する為の関数が入っているスクリプトです。")
これでmyclac.pyを直接実行した際は”これはBMIを計算する為の関数が入っているスクリプトです。”と出力されますが、呼び出された際には__name__が__main__とならない為実行されません。
これは関数実行サンプルを記述したりする際に使われます。
BMIを計算する程度の簡単な関数にサンプルを用意する必要はありませんが、
例えば、とあるアプリを開発していて、そのアプリにはとあるサイトをスクレイピングして内容を反映させる仕組みがあるとします。
(これは物の価格を比較したりするアプリ等で実際によく行われている処理です。)
しかし、スクレイピング元のサイトがHTML等を変更してアプリにエラーが発生してしまいました。
原因は分かりません。
このエラーの原因を突き止める為に毎回mainスクリプトを動かすのは効率が悪いです。
しかし、モジュール側でサンプルスクリプトを用意していれば、スクレイピングが上手く行えていないことが分かりスムーズに解決できることでしょう。
まとめ
如何でしたでしょうか。
今回はpythonの関数に関する内容をまとめました。関数を覚えるとよりスマートなコードが記述できるようになることでしょう。
関数はこの次に解説するクラスの内容にも大きく関わってきますので、是非とも習得しておきましょう。