Pythonにおいて、関数は「名前の付いたコード」であると同時に「メソッド」でもあります
変数はオブジェクトを使いまわすためのものでしたが、メソッドは処理を再利用するための仕組みです
関数もメソッドもオブジェクトに対して実行しますが、関数はモジュールに書かれた他のコードから切り離されていて「内部のオブジェクトが用意されている」という違いがあります
オブジェクトを定義する「クラス」の内部で書かれたものを「メソッド」それ以外の場所、もしくはモジュールに直接書かれたものを関数と呼び区別します
関数もメソッドも構造自体は同じものなので、書き方もルールも同じです
defキーワードに続けて関数名を書き、呼び出し元からの値を受け取るパラメーターを()に書き最後に
:(コロン)を付けます
インデントして書いた範囲が関数のブロックとして扱われます
- def 関数名(パラメーター1,パラメーター2,…):
処理
・・・
return 戻り値
パラメーターは、関数の呼び出し元から値を受け取るためのもので、変数と同じように任意の名前を付けることができます
仮引数と呼ばれることもあります
また、仮引数に対し呼び出し元から渡されるものを実引数とよびます
パラメーターが必要なければ()内は空欄にしておきます
関数で処理した結果を呼び出し元に渡したい場合は戻り値を返すようにします
「return 戻り値」と書き、戻り値にはTrueやFalseのようなリテラルや変数を指定できます
関数名(引数)と書いて呼び出すと、引数に指定した値が関数側のパラメーターにコピーされます
関数内部の処理が順次実行され、最後にreturnで指定した戻り値が呼び出し元に返されます
ただ、戻り値が必要ない場合はreturnステーメントは書く必要はないです
returnがない関数は「処理のみを行う関数」になります
パラメーター(enemy)が戻り値なので変数resultには「攻撃」が代入されます
以降は変数「attack(‘攻撃’)」と入力すれば関数を呼び出せます
パラメーターの指定
呼び出し側の引数と関数の順番は同じである必要があります
デフォルトパラメーター
パラメーターをとる関数には、必ずしも引数を渡さなくてはいけないわけではありません
関数側でパラメーターの初期値を指定しておけば、引数がない場合に指定した値が使用されるようになります
これをデフォルトパラメーターと呼びます
デフォルトパラメーターは、デフォルト値を持たないパラメーターの後に書く必要があります
引数がひとつだけなのでこの値がパラメーターaに渡されます
もし、引数を2つ指定したらパラメーターbのデフォルト値が上書きされます
伸縮自在のパラメーター
パラメーター名の前に*(アスタリスク)を付けると可変長パラメーターになります
「*パラメーター名」と書くとパラメーターがタプルとして扱われます
キーと値がセットになったパラメーター
「**パラメーター」と書くと、パラメーターが辞書型(dict)になります
キーワード引数を渡すと、キーワードがキーに、その値がキーワードの値になります
キーは変数名と同じようにアルファベットである必要があります
辞書型パラメーターの書式は
- def 関数名(**○○○) … 辞書型パラメーターのみ
- def 関数名(パラメーター1,パラメーター2,**○○○) … 位置型パラの後に辞書型
- def 関数名(パラメーター1,パラメーター2,*○○○,**○○○) … 位置型、可変長、辞書型の順でパラメータ設定
関数オブジェクトと高階関数
Pythonでは、すべてのものがオブジェクトです
関数も例外ではありません
他のオブジェクトと同様に変数に代入したり、ほかの関数に引数として渡すことや戻り値として関数を受け取ることもできます
まずは、service()関数を定義します
次に、パラメーターで関数を取得し実行する関数を定義します
関数をパラメーターで取得する、または戻り値として返す関数を高階関数と呼びます
service()関数を引数にしてrun_something関数()を呼び出します
run_somethingにsurviceを引数として渡すと、survice関数が実行されました
Pythonではsurvice()と書くと関数呼び出しを意味し、surviceと()なしで書くとオブジェクトとして扱われるからです
関数内関数とクロージャー
関数内で関数を定義できます
複雑な処理を内部の関数に任せることで、コードの重複を避けることができます
関数内関数は、パラメーターの値に文字列を追加できます
関数内関数の便利なところは、クロージャーとしてつかえるところです
クロージャーとは、引数をセットして関数を呼び出すコードを作っておき、それを後で実行できるようにするものです
関数を呼び出すパターンが事前にわかっているなら、それを記録しておいて必要なときに実行されるようにするといった使い方ができます
小さな関数は処理部だけの「式」にしてしまう[ラムダ式]
関数内関数やクロージャーのように関数内部で関数を定義するのではなく、内部で別の関数を読んできて処理したい時があります
例えとしては、データを加工する関数を別に定義しておいて、それをforループの中で呼び出すような処理です
今回は、パラメーターで取得した攻撃リストの要素を順番に画面に表示する関数を定義します
ここで、赤丸部分の式をラムダ式に置き換えてみると
こうなります
ラムダ式の書式は
- lambda パラメーター1,パラメーター2, ・・・ 処理
ラムダ式にしたことで、impact()関数が不要になりました
ラムダ式は名前のない処理部だけの関数であることから無名関数ともいわれます