Python

【Python初心者】 関数の基本を理解しよう。

こんにちは(@t_kun_kamakiri)(‘◇’)ゞ

この記事ではPythonの「関数」について解説します。

この記事で学ぶこと

  1. 関数の基本的な書き方
  2. 関数に引数を使った書き方
  3. 関数の中に関数を書く(クロージャー)

Pytonの関数は以下の2通りを覚えておきましょう。

  • 「def 関数名()」の基本的な書き方
  • 「lambda パラメータ1, パラメータ2 : 処理」の書き方
 
今回は「def 関数名()」の基本的な書き方のみに絞った話をします。
 
使用環境を示しておかないと混乱しそうなのでちゃんと書いておきます(^^)/
 

【Pythonの使用環境について】
Anaconda
Google Colaboratory
当ブログはこれをメインに使った計算結果です。

関連記事

 

☟書籍も紹介しておきます。
こちらの本がPython初心者が挫折することなく勉強できる本です。
(本記事のようのPython使用環境と異なりますが、とてもわかりやすいので全く問題ありません)

確かな力が身につくPython「超」入門 (確かな力が身につく「超」入門シリーズ)

確かな力が身につくPython「超」入門 (確かな力が身につく「超」入門シリーズ)

鎌田 正浩
2,728円(01/24 11:19時点)
発売日: 2016/03/16
Amazonの情報を掲載しています
スポンサーリンク

Pythonの関数とは

 

Pythonの関数は「色々な機能がひとつにまとまったもの」を意味します。

機能とは「したい処理内容」のことを意味しています。

カマキリ

具体例を見ながら学びましょう。

例えば、部屋の温度を下げるため冷房を効かせたいとします。
この時に、人がすることは冷房ボタンを押すだけです。
冷房ボタンを押すことにより、冷房が冷風を送るという動作が行われます。

もちろんリモコンボタンはなんでもしてくれる便利道具ではなく、あらかじめ決められた処理内容が冷房機器には設定されていて、ボタンを押すという処理を呼び出す動作をすることで、冷風を送るという処理が行われたということになります。

以下で具体的にコードを書いてみましょう。

Pythonの関数の書式

 

Pythonの関数の機能を使うには「def」というキーワードと使います。

defはdefineから来ており、「関数をdefineする」という意味です。

関数の書式

※注意点

  1. defの最後には「:」を忘れないこと。(これはif文でも同じです)
  2. 処理1、処理2、・・・の前は「tabスペース」を設けること。
    Pythonに対応したエディタであれば自動的に「tabスペース」を作ってくれますが、専用でないエディタであれば自分で「tabスペース」を設ける必要があります。
    この「tabスペース」のPythonルールはインデントと呼ばれており、プログラミングの記述をわかりやすくするためのルールです。

※インデントがおかしいとエラーになるため必ずインデントは意識するようにしましょう。
イ別とは思ってはいけないということですね。

Pythonの関数を使ってみよう

仕組みや概念の理解も大事ですが、とりあえず使って慣れることの方がもっと大事です。

実際にコードを書いてみましょう。

【結果】

「cool()」という名前の関数を定義して、その中にprint文で「冷風を送る」と「涼しいかい?」と出力する処理を書いています。

しかし、関数を定義しただけでは何も動作はしません。

その後に、「cool()」と書いて関数を呼び出すことで、関数内の処理が行われます。

ここで注意があります。

関数の呼び出しは、関数を定義した後に記述しなければエラーになってしまいます。
例えば、関数の呼び出しと関数の定義の順番を逆にしてみます。

【結果】

上記のようなエラーとなります。
エラー内容は、「’cool_1’」というな名前のオブジェクトが定義されていないとなっています。

関数の中でif文を使う

【結果】

「temp = 20」なので、関数を呼び出した際の「temp == 20」が真となるため、if文内の、

  • print(‘温度は%d℃です。’ % temp)
  • print(“涼しいかい?”)

この2つの処理が行われました。

※ちなみに、「print(‘温度は%d℃です。’ % temp)」は、%dにtempの変数が入る記述方法です。
このように、文字列中の変換指定子%d%sを書くと、文字列の中に「% temp」の変数の値が%dに代入されます。

変換指定子は整数が%d、浮動小数点が%f、文字列が%s。詳しくは公式ドキュメント参照に下ください。

関数に引数を入れて処理結果を返す(円の周長さと面積を計算)

1つの引数を設定

変数として半径を入力して、関数の中で円の周長さと面積を計算してもらいましょう。

このような処理を行うには関数に引数を入れる必要があります。

実際にコードを書いてみましょう。

【結果】

※補足説明

  1. import mathで円周率「math.pi」を使えるようにしています。
  2. 関数defにradiを入れると、周長Lと円の面積areaをradiに応じて計算してくれます。
  3. その結果を「return L, area」とすることで計算したデータを返すということをしてくれます。

ちなみに結果が「(62.83185307179586, 314.1592653589793)」と、()となっているためタプル型として値が返ってきているということになります。

2つ以上の引数を設定

引数には2つ以上設定することもできます。

例えば薄肉円筒の\(\theta\)方向の応力を計算したいとします。

薄肉円筒の\(\theta\)方向の応力は、\(\sigma=\frac{pD}{2t}\)となります。

では、実際にコードを書いてみましょう。

【結果】

関数「calc」を定義して「dia, press」という直径と圧力の2つの引数を設定しています。

あとは、内部の処理で、「sigma_theta = (press * dia)/(2.0 * t) 」としていますが、これは薄肉円筒の\(\theta\)方向の応力\(\sigma=\frac{pD}{4t}\)を計算式ですね。

それをreturn文で値を返すようにしています。

そして、print(‘応力は{}Paです’.format(round(calc(50, 100),2)))で小数点第二位までをprint文の{}内に埋め込むようにして出力して今sう。


以上のような計算式を用意しておくと、強度が1000Pa以上だと不足するという判断をif文で用意しておけば以下のような強度の判断をする処理が可能になります。

【結果】

「calc(50, 100)」を計算した結果は1041.67で1000より大きいため、if文内の「強度不足です」がprint文で出力されています。


 

以上のように引数は2つでも3つでも構いません。

今回の場合でも板厚tをさらに引数にして、「直径、圧力、板厚」で強度不足を判断するプログラムを作っても良いでしょう。

関数の引数に可変長パラメータを設定

先ほどまでは、引数の数が決まっている状態でしたが、引数の数を可変にすることができます。

可変長パラメータ

  • 可変長パラメータ(タプル型)
  • キーと値がセットになった可変長パラメータ(辞書型)

可変長パラメータには、「タプル型」と「辞書型」にして引数を取り扱う設定方法があります。

可変長パラメータ(タプル型)

可変長パラメータを引数にするために「アスタリスク *」を変数の前に付けて引数を設定します。

以上のようなコードを具体的に書いて実行してみましょう。

【結果】

今回、関数の引数として「**args」としましたが、慣習としてそのような変数名にしましたが、任意の変数名でも構いません。
例えば、以下のようにしても同じ結果を得ることができます。

大事なのは、関数の中で引数の名前さえ統一していれば良いということです。

上の例では、複数の引数と関数に引き渡しているのですが、その変数はどのような型で関数に引き渡されているのでしょうか。
それを確認するために、print文でtype()を使って引数の型を確認してみましょう。

【結果】

引数の要素がタプル型としてセットになっているのが確認できますね。

キーと値がセットになった可変長パラメータ(辞書型)

また、辞書型として引数を設定することもできます。
それには「アスタリスク2つ **」を変数の前に付けて引数を設定します。

実際にコードを書いてみましょう。

【結果】

関数を呼び出すときに、「n_month(January=’1′,February=’2′,March=3)」として引数に「 キー = 値 」という形で変数を引き渡しています。

引き渡す「キー」はデフォルトで文字列になっていますが、「値」については文字列でも数値型でもどちらでも構いません。
上の例でも、「March=3」として引数に渡しているので、「’March’: 3」と値が数値型になって出力されているのが確認できますね。

関数を引数にする

引数にできるのはオブジェクトであるため、オブジェクトである関数も設定することができます。

具体的にコードを書きながら見てみましょう。

【結果】

何が起こったのかを絵にまとめてみました。

  • 最後の行で「All_run(calc, 10, 20)」して「calc 関数」と「10,20 値」を引数として引き渡しています。
  • funcには「2つの引数」を渡して処理するということを行います。
    このときの。funcは「calc関数」を使えとい指示になっています。
  • そして、calc関数に「2つの引数」が渡たします。
    今回は2つの引数の値の和を計算する処理を行って、print文で出力するというのを行っています。

先ほどの可変長パラメータを使うと引数の数を変えることもできますね。

【結果】

関数内関数とクロージャー

関数の中に関数を記述する方法についても見ておきましょう。

関数内部で同じような処理を行う場合は重複を避けるために関数にまとめておくのが良いですよね。

関数内関数

実際にコードを書いてみましょう。

【結果】

以上のように関数の中に関数を書いて処理をまとめておくことがdけいます。

クロージャー

関数の中に関数を書く方法にクロージャーというのがあります。

クロージャ関数
変数に関数を格納するとその関数定義自体が格納されることを利用する。
※関数を状態ごと保持したオブジェクト

ちょっとよくわからないかもしれないですね(*_*;

実際にコードを書いてみましょう。

【結果】

少し理解が難しいかもしれませんが、ひとつひとつ見ていけば良いでしょう。

  • 「c = All_func(10, 20)」で引数に「10, 20」を渡しています。
    それが「All_func(a,b)」に引き渡されているがわかりますね。
  • 「 run_calc()」がクロージャーの部分です。
    最後に「return  a + b」として引き渡された引数の和を計算して返すようにしています。
  • 「return run_calc」で関数のオブジェクトを返すようにしています。
    なので、「c = All_func(10, 20)」では関数オブジェクトが生成されているだけになります。
    なので「print(‘c’)」では何も出力されず関数オブジェクトのメモリなどが表示されているだけです。
    cの中身の処理を行いたい場合は「c()」とすればよいですね。

大事なのはクロージャーは関数のオブジェクトを返すということです。

もうひとつ例を見てみます。
生成したcに引数を渡してやります。

【結果】

cの引数に100を渡しているので、「run_calc(add)」のaddが100になって、「return a + b + add」で処理が行われているということです。

まだ、イメージがつきにくいかもしれませんね。

例えば、先ほど例に出した薄肉円筒の\(\theta\)方向の応力を計算を再度、クロージャーを使って計算してみます。

薄肉円筒の\(\theta\)方向の応力は、\(\sigma=\frac{pD}{4t}\)となります。

すでに、直径と圧力はそれぞれ「直径=50mm」「圧力=100kPa」と決まっているとして、残り板厚をどうするかとなっている状況を想定してみます

では、実際にコードを書いてみましょう。

【結果】

「sigma_L = All_func(50, 100)」では、まだ直径と圧力しか入力しておらず、sigma_L にrun_calc関数のオブジェクトが代入されただけです。

結果を出力するために「sigma_L(1.2)」として引数を渡すことで、run_calc関数内の「return sigma_theta 」が出力されたというわけです。

まとめ

ここまでで、Pythonにおける関数の基本的な内容をお話ししました。

今回学んだこと

  1. 関数の基本的な書き方
  2. 関数に引数を使った書き方
  3. 関数の中に関数を書く(クロージャー)

まだ、Pythonの関数には学ぶことがあり、例えば、

  • ラムダ式:小さな処理を書く
  • ジェネレーター:1つずつ取り出す処理(yield関数)
  • デコレーター:関数に機能を追加

などは、次回の記事内容としたいと思います。

前回の記事はこちら

おすすめ参考書

独習Python

独習Python

山田 祥寛
2,970円(01/24 13:03時点)
発売日: 2020/06/22
Amazonの情報を掲載しています
現場ですぐに使える! Pythonプログラミング逆引き大全 357の極意

現場ですぐに使える! Pythonプログラミング逆引き大全 357の極意

俊哉, 金城
3,190円(01/23 23:39時点)
発売日: 2020/05/16
Amazonの情報を掲載しています
関連記事もどうぞ