🔙
🔝

関数

関数の仕組みを知り、関数をDIYすることができるようになります👍

Chatpter.1 - 関数のしくみ

関数のしくみ

  • 関数は、受け取った引数を使って決められた処理をする仕事を担います。

    1. 引数を受け取る (省略可)
    2. 関数の処理を実行する
    3. 戻り値を返す (省略可)

    2番目だけですね、必要なのは A's
    しかし厳密にはこの3つがあって「関数」と言うことになっています。

    2番目の部分に関数の機能となるプログラムを書きます。


  • 初めはちょっと難しく感じるかもしれません。

  • でも読み進めていくと、途中から急に関数というものが理解できるようになると思います。

  • 関数はこんな風に書きます。

  • def function(a, b):  # 関数を定義する
    	c = a + b  # 関数の機能部分
    	return c   # 関数が作った戻り値
    
  • 一行目の最初に書かれている def というのが「関数宣言」です。

    ♪ 値を中に もらう前に 言っておきたい 事がある ♪

  • その言っておきたい事というのが def です。

  • defdefine (定義する) の def です。

  • def の末尾に : があります。
    と同じように、インデントをつけることで関数の範囲を示します。

  • def() の間にあるのが、おなじみの「関数名」です。

  • 今まで使ってきた関数sorted()とかの sorted の部分です。

  • 例では関数という意味でテキトーに function と名付けましたが、関数の機能に合った名前を付けておかないと、どんな機能の関数なのかがわからなくなってしまいます。

  • その次の () が、引数を受け取る所です。

    (a, b) は、例えば、

    def function(a, b):  # 関数を定義する
    	c = a + b  # 関数の機能部分
    	return c   # 関数が作った戻り値
    	
    function(1, 2)  # ← 「関数を呼び出す」と言います
    

    として引数を渡した時、
    a には 1b には 2 が渡されます。

  • 渡す引数の個数と、受け取る引数の個数は同じでなければいけません。

  • 異なるとエラーになります。

  • 引数を変数にした場合、渡す側の変数名受け取る側の変数名は異なっていても構いません。値を「見せるだけ」なので。

  • それと、引数の値は関数に「見せるだけ」なので、可変不変は関係ありませんし、値であればどんな型や形のものでも渡せます。

  • 二行目の

    	c = a + b
    

    は、それぞれ受け取った引数の ab の値を使って足し算をした結果を c に代入しています。

    ここが関数の機能となるプログラムになります。

  • そして最後の行の

    	return c
    

    c の値を戻り値として、呼び出した関数の所に返します。


  • 戻り値は最終的に呼び出した関数が戻り値に化けて、この関数の一連の動作が終了します。

  • function(1, 2)
    
    3
    
    def function(a, b):  # 関数を定義する
    	c = a + b  # 関数の機能部分
    	return c   # 関数が作った戻り値
    
    print(function(1, 2))
    
    3
    引数を変えて試してみよう!

    これでこのプログラムが、理解して読めるようになったはずです。

Chatpter.2 - 自分で関数をつくる

ずっと自分には無理と思っていた事を或る時恐るゝゝやってみたら、実に呆気無く容易く出来てしまった時のあの感動を!

2.1 - 関数の命名

ハンドメイド関数にメイ名する

  • 関数名としてふさわしい命名のコツは、まず関数名を見て「機能が一目でわかる」ことです。

  • 次に「名前の最初を動詞にする」ことです。

  • 特定の処理を「する」機能なので、動詞が適切となります。

  • 英語で書きます。英語がわからないと途端につまづきます。

  • 無料の ChatGPT先生の出番です。

  • どうしてもうまく命名できないという場合は、とりあえずはローマ字表記の日本語でも構いません。

    def tasizan(a, b):
    
    def kansuu1(a, b):  # 足し算する
    
    def f1(a, b):  # 足し算する
    

    あとで考えるパターンです。😸

  • 試しに ChatGPT先生に考えていただきましょう。
    先生、お願いしやす。

  • 😾 あなた
          a と b を足し算する機能に適した関数名をいくつか提案してください。

  •      

    もちろんです。以下は、a と b を足し算する機能に適した関数名のいくつかです。

    1. add_numbers
    2. sum_values
    3. calculate_sum
    4. add
    5. compute_total

         

    これらの関数名はわかりやすく、機能に対して適切なものです。どれか気に入ったものがあれば、それをお使いいただけます。

  • ご苦労様でした、先生!😼
    また次もよろしくお願い致しやす!

  • add でいいや。(´∀`*)

  • def add(a, b):
    	c = a + b
    	return c
    

    これで以前より適した関数名になったかと思います。

2.2 - 関数のプログラム部分

関数のお役目を作る

  • 関数で書いたプログラム。

  • def add(a, b):
    	c = a + b  # ← この部分
    	return c
    
    print(add(1, 2))
    
  • これを今までの書き方で書くと、こんな感じです。

    a, b = 1, 2
    c = a + b
    print(c)
    
  • 一見、関数のほうが回りくどくて面倒に思えるかもしれません。

  • 短いプログラムでは利便さがよくわかりませんね。


  • 関数を使うメリットは、足し算をするたびに「何度も同じプログラムを書かなくて済む」点です。

  • 要するに、プログラムを「再利用」できるようにするのです。

  • 引数を与えるだけであとは関数が仕事してくれます。

  • def add(a, b):
    	c = a + b
    	return c
    
    print(add(1, 2))
    print(add(2, 3))
    print(add(5, 5))
    print(add(3, 8))
    print(add(10, 20))
    
    3
    5
    10
    11
    30

    今まで使ってきたどの関数も「引数を与えるだけ」で関数が担当する仕事を請け負ってくれていました。

  • ここでまた Fizz Buzz を、今度は関数を使って書いてみます。

  • ふつうの書き方

    for i in range(1, 101):
    	if i % 3 == 0 and i % 5 == 0:
    		print('アホイヌ')
    	elif i % 3 == 0:
    		print('アホ')
    	elif i % 5 == 0:
    		print('イヌ')
    	else:
    		print(i)
    

    関数を使った書き方

    def fizzbuzz(x):
    	if x % 3 == 0 and x % 5 == 0:
    		return 'アホイヌ'
    	elif x % 3 == 0:
    		return 'アホ'
    	elif x % 5 == 0:
    		return 'イヌ'
    	else:
    		return x
    
    for i in range(1, 101):
    	print(fizzbuzz(i))
    

    ※ 出力結果は省略します

  • どういう風に違うかというと、ふつうの書き方の場合は文の中身が大きくなると、文全体がごちゃごちゃしてわかりにくくなります。

  • 関数を使うと、Fizz Buzz のプログラムの部分が別の場所に書かれているので、そのプログラムの部分が何なのか、文が何をしているのかがわかりやすくなります。

  • メインプログラムがシンプルになると、プログラム全体の流れを把握しやすくなります。

  • 代わりに Fizz Buzz のプログラム部分があった所に関数名を置いて「この部分は i を引数に fizz buzz をする」とざっくりコメントしています。

  • なので、関数の命名はとても重要です。

  • 「add でいいや。(´∀`*)」とか言ってちゃいけないのです。😅

  • 「add にしよう!」と言いましょう。😊

2.3 - 引数なし

引数を与えない関数の使い方

  • 「引数なし」の関数の使い方を説明します。

    def output_screen():
    	print('Hello world!')
    	return
    
    output_screen()
    
    Hello world!

    完全に関数の中だけで処理を完結させています。なので、戻り値もありません。

  • 戻り値だけ設定すると、

    def output_screen():
    	return 'Hello world!'
    
    print(output_screen())
    
    Hello world!

    という形で書きます。

  • 引数なしの関数も「再利用」を目的として作られます。

  • 他にも、メインプログラム中に書かれた長くなってしまったプログラムを関数化してすっきり見通し良くする目的でも行なったりします。たとえ一回しか使わないプログラムだったとしても。

  • もちろんそこに関数名を印に置く形になります。

  • 早い話が「移転」ですね。

2.4 - キーワード引数

key= を作ってみる

  • むずかしくないよー。簡単よー。

  • 「キーワード引数」というのは、sorted()などで使ってた key=lambda ・・ とか reverse=True とかです。

  • 今からこれを自分で作ります。

    def output_screen(key=False):
    	if key:
    		return 'Kanon'
    	else:
    		return 'One'
    
    print(output_screen(key=True))
    
    Kanon
  • 引数を渡す際、キーワード引数は省略できます。

  • キーワード引数が省略された場合は「変数(キーワード)に初期値が代入」されます。

  • 関数の ( ) に入っている key というのが、関数内でそのまま使われる変数になります。

  • まず、keyFalse が代入されます。key=False

  • キーワード引数がある場合
    その引数は key に上書き代入されます。key=引数
    省略された場合
    key=False のままです。
  • 関数の呼び出し(最下行)の中の key=True で、key の値を True にして引数として関数に渡しています。

  • 結果、文で keyTrue と判定されて 'Kanon' が戻り値として返ります。


  • このキーワード引数を省略すると、

    print(output_screen())
    
    One

    初期値の key=False が適用されて One と出力されます。

  • 引数なしにしてみよう!
  • キーワードを作ってキーワードで引数を渡すと、引数を渡す順番が不問となります。辞書のキーと値の関係と同じです。

  • def output_screen(key1=False, key2=False, key3=False):
    	if key1 and key2 and key3:
    		return 'Kanon AIR CLANNAD'
    	else:
    		return 'One'
    
    print(output_screen(key2=True, key3=True, key1=True))
    
    Kanon AIR CLANNAD

    def output_screen(key1=False, key2=False, key3=False):
    	return key1, key2, key3  # ← 最後はこの順番で出力される
    
    print('key1=省略,', 'key2=True,', 'key3=省略')
    print(output_screen(key2=True))
    
    key1=省略, key2=True, key3=省略
    (False, True, False)
  • キーワードはそのまま変数になりますので、変数の命名規則が適用されます。

  • 規則の範囲内でしたらどんな名前を付けてもOKです。

  • 長すぎる名前は扱いにくくなりますので、省略形にしてなるべく短くすることが多いです。

  • キーワード引数を設定することによって、作った関数を柔軟にすることができます。

  • sorted()関数のように、ただリストを昇順にソートするだけでなく、キーワード引数を設定して降順ソートにも対応したり、lambdaなどの関数を使ってあらゆる方法でソートすることが出来るようになります。

  • キーワード引数が無ければ「昇順ソートの関数」と「降順ソートの関数」とを、2つ用意しなければなりません。

  • これをキーワード引数を使うことによって1つにまとめています。

  • print()関数も end=sep= のおかげで、とても便利に使わせてもらえています。 print()関数マジ神。

  • 初めのうちは先の事なんて考えてる余裕もないのでなかなか自分で作って使う機会はないかもしれません。

  • でもキーワード引数を使うことによって、1つの関数が多機能になります。

  • 逆に関数を使用する側としてみれば「ソートするならsorted()」と1つ覚えておくだけで済みます。

  • 使いどころを見つけたら、ぜひ使ってみてください。

2.5 - return で戻り値を返す

return

  • 関数の中に return は1つでなければならないということはありません。

  • 複数あっても、return となった所で return します。

  • return する時は、その後ろの値を「戻り値」にして返し、関数を終了します。

  • 先ほどのプログラムを例にします。

    def output_screen(key=False):
    	if key:
    		return 'Kanon'
    	else:
    		return 'One'
    
    print(output_screen(key=True))
    
    Kanon

    return が2つありますが、True側と False側のそれぞれに return があり、文の判定後にそれぞれの return で返っていきます。

  • 関数の範囲はインデントをつけることで示されていますので、return が無くても、インデントの最後を越えた場合は、そこで関数が正常終了します。

  • これは文の else: を省略した時と同じ挙動です。

  • ただし、return がある場合も同じですが、戻り値が無い場合は、戻り値は「None」で返ります。

  • None は「値が無いという」です。

  • 最後に戻り値を変数に代入して使う場合などでは、意図しない形で None が返らないように気を付けてください。

  • 👇こういうことです。👇

    def output_screen(key=False):
    	if key:
    		return 'Kanon'
    
    print(output_screen())
    
    None

    None って言われても・・・。


  • わかっていてもたまにやりますが・・・やるというより「なってしまう」が近いですね。😽

  • このプログラムは簡潔に書くことができます。

    def output_screen(key=False):
    	return 'Kanon' if key else 'One'
    
    print(output_screen(key=True))
    
    Kanon

    return の後にいきなり内包表記文を書き、その判定結果を戻り値にして return で返しています。

    チート行為ではなく、日常的に使われる記法です。
    (プログラミングではむしろ、チートは神です。チーターもネコ科)

  • 内包表記のところが内包されていないように見えますが、本来なら書かれている ( ) が省略された形であんな見た目になっているのです。問題なし!👍

  • return 'Kanon' if key else 'One'
    
    return ('Kanon' if key else 'One')
    
    return ('Kanon')
    
    return 'Kanon'
    
  • 要素が1つだけの時は ( ) が自動で省略されます。

  • あの 'Kanon' if key else 'One' も、値を1つ作る前の1要素です。

2.6 - return で多重ループを一気に抜ける

関数を使えばフラグが不要に

  • 2章の「bool型 True と False」の Chatpter.5 では、フラグを立てるやり方で多重ループを抜けるやり方を紹介しました。

  • その時にまだむずかしいと言ったやり方というのがこれ、関数の return を使って一気に多重ループを抜ける方法です。


  • と言っても、もうお判りですよね。😸

  • 関数の中で多重ループを作り、return の特性を利用して関数を終えれば、何重ループであってもあっさり抜けてしまいます。

  • def loops(cat):
    	while True:
    		while True:
    			while True:
    				while True:
    					while True:
    						return cat
    print(loops('😺'))
    
    😺

    シュレディンガーですら百歩も退いてしまうであろう、何ともえげつない閉じ込め方ですが、これでも一度で脱出してしまいます。さすが液体。

  • 多重ループの脱出でフラグが必要になったら、即座にまとめて関数にしてしまいましょう。