Pythonの関数の「定義」と「呼び出し」が基礎からわかる

Python

「Pythonはある程度学習しているけれど、関数を作る方法がよくわからない。それ以前に実は、関数とはどういうものかをちゃんと説明できる自信がない…」

本記事を読めば、Python3の【関数】を作る手順について核心から理解できるようになります。

関数を一言で表すと、「プログラム内で使うためのある特定の処理をまとめたもの」です。

プログラムを書いている時、繰り返し出てくるような全く同じ部分は関数にまとめた方が、毎回同じことを書かなくてもいいので楽です。

また、変更点や間違いなどを発見した時に1回で修正できる点も関数を使うメリットです。

関数についての深い理解は、今後のプログラミング学習で高いレベルを目指すための頼もしい装備のひとつになります。
関数をこれからマスターしたいあなたにも、もう一度学び直したいあなたにも必見の内容です!

関数の定義の方法

まず、最初に関数を定義する方法についてです。

関数を定義するためには、Pythonで決められているルールを守る必要があります。
これを知っておかないと、エラーが発生してしまい、正常に処理されません。

先頭にdefというキーワードを記述する

関数の先頭には、def(definition=定義)というキーワードを記述します。
関数を定義する時には、「def」というキーワードに続けて定義したい関数の名前を記述します。

【書式】

def 関数名(引数):
 関数の処理
 return 戻り値

関数についての全体像と基本的な構造について見ておきます。
関数は、次の4つのパーツから構成されています。

関数名

プログラム内で関数を扱う名前です。
関数を呼び出すときには、コード内で関数名を入力します。

関数名は使用できる文字列で命名する

関数名については、一部の例外を除いて基本的に自由に入力してOKです。
ただし例外として、以下のような命名規則があるので注意しましょう。

  • 半角の英小文字・半角数字を使う
  • 関数名の1文字目には半角数字を使用できない
  • 単語の区切りは「_(アンダーバー)」
  • 「予約語(Pythonが既に使用しているキーワード)」は使えない
  • 「組み込み関数の名前」は使えない

引数(ひきすう)

引数は関数が処理を実行する時に使用するデータのことです。(省略可能)

例えば部品を組み立てる機械があっても、材料を入れなければ完成品は出てきません。
関数もそれと同じく、引数を入力することで結果が出力されるイメージです。

引数には、文字・文字列・数字なんでも与えることができます。

複数の引数がある場合は、1つずつカンマで区切ります。
引数を持たない場合、()の中は空白のままです。

関数の「処理」の部分

組み立て機械にあたるのが「関数の処理」の部分です。
式などが記述されており、与えられた引数を使って処理を実行します。

return文で戻り値を設定する

関数の処理によって出力される戻り値を返します。
関数の定義では、「return文」を使うのがオーソドックスです。
戻り値を返さない関数では、return文は省略できます。

よく間違えがちですが、printとreturnは似て非なるものです。
・returnは値を返すだけ。
・printはコンソール上に表示するだけ。

実際に関数を定義する

これらのルールを踏まえて、実際に関数を定義してみましょう。
関数を定義する際の最も基本的な書式は次のようになります。

def 関数名(引数):
関数の処理
return 戻り値

関数を定義するときの注意点としては、「関数の内部」と「関数の外部」を区別することです。
一見すると外部の変数などを自由に代入できそうにも見えますが、プログラム上では明確な区別がされています。
あくまで、関数の内部と外部は別のものだと理解しておきましょう。

【コード例】

def cook(taste, smell, look):
    score = taste + smell + look 
    return score

次の例では、料理の点数を評価するcook関数を定義してみました。
引数には「taste(味)」「smell(匂い)」「look(見た目)」を設定し、
数値を入力すると、「score(料理の得点)」を計算して、戻り値として出力します。

定義された関数は簡単に呼び出せる

先ほど定義した関数は、あくまで定義されただけです。
実際に呼び出して使うには、さらにコードを記述する必要があります。

【書式】

関数名()

呼び出す方法は、関数名を入力した後、右隣に()を入力するだけです。
引数の値を渡す場合には、()の中に入力します。

cook関数は定義するときに引数を設定しているので、呼び出すときに引数の値を与えればscoreが戻り値として出力されます。

【コード例】

#関数を定義
def cook(taste, smell, look):
    score = taste + smell + look
    return score

#関数を実行して出力
print(cook(50, 80, 70))

【出力結果】

200

ちなみに「組み込み関数」という、Pythonに標準装備されている関数も同じ方法で呼び出すことができます。
組み込み関数は初めから定義されているので、特別な準備なく使うことが可能です。

関数の引数と戻り値は省略可能

引数や戻り値を省略できる関数の場合、記述せずに省略しても問題ありません。

引数のない関数

引数は必ずしも必要という訳ではなく、引数がなくても関数を定義できます。

【コード例①】

def test(a):
    print('Hello')
 
test(1)

【出力結果①】

Hello

コード例①は引数に何を入れても、結果の変わらないコードです。
()には引数が入るはずなのですが、必要ないので省略してみましょう。

【コード例②】

def test():
    print('Hello')
 
test()

【出力結果②】

Hello

コード例②のように引数を省略したコードでも、問題なく処理できました。

戻り値のない関数

戻り値とは、主に再利用したい値がある時に使用するものです。
再利用の予定がなければ、わざわざreturnで戻り値を返す必要はありません。

【コード例】

def hello():
    print('Hello')
hello()

【出力結果】

Hello

関数の定義と「制御構文」・「再帰呼び出し」

これまで見てきた関数定義の基本をもとに、もう少し複雑な処理をする関数を作成してみます。
難解な部分もありますが、プログラムの幅を広げるにはうってつけの練習です。

「制御構文」を使った関数の定義

まず、制御構文を利用した関数を見てみます。
制御構文とは、プログラム実行の流れをコントロールするための構文です。

ここでは、特にif文による条件分岐を処理として入れ込みます。
関数内部のif文は、その条件式が「True」の値をとるときはif文の処理が行われます。
「False」の場合にはif文による処理は行われず、関数全体における次の処理にスキップするようなイメージです。

例として、cook関数の処理にif文を入れて定義してみます。
味・匂い・見た目の点数(関数呼び出しの際の引数の値)によって料理の出来を評価するシステムです。

まず、最も優先される処理として、味が20点以下の場合は「stop eating」と表示されます。

【コード例】

#関数を定義
def cook(taste, smell, look): 
    if taste <= 20:
        return 'stop eating' 
    elif taste + smell + look >= 200:
        return 'yummy!' 
    return 'edible'

#関数を実行して出力
print(cook (10, 100, 100))

【出力結果】

‘stop eating’

また、次に優先される処理として、総合点が200点以上なら「yummy!」と表示されます。

【コード例】

#関数を定義
def cook(taste, smell, look): 
    if taste <= 20:
        return 'stop eating' 
    elif taste + smell + look >= 200:
        return 'yummy!' 
    return 'edible'

#関数を実行して出力
print(cook(80, 90, 60))

【出力結果】

‘yummy!’

それ以外の場合は「edible(食べられる)」が示されます。

【コード例】

#関数を定義
def cook(taste, smell, look): 
    if taste <= 20:
        return 'stop eating' 
    elif taste + smell + look >= 200:
        return 'yummy!' 
    return 'edible'

#関数を実行して出力
cook (30, 50, 40)

【出力結果】

edible

if文では、このような場合にelse部を使っていました。
しかし関数では、if文の処理が実行されなければ自動的に次の処理に移行します。
そのため結果として「if文以外の場合」、すなわちelse部に似た役割を持つのです。

「再帰呼び出し」で関数の処理を繰り返す

関数を定義する際の処理に、その関数自体のシステムを入れ込んでしまうことを「再帰呼び出し」といいます。
少しややこしいですが、要は関数内部で行われる処理にその関数自体を使うということです。

その結果として、メビウスの輪のように処理が繰り返されることになります。
しかし、関数内部には処理の優先順位があるので、それを利用すれば任意の範囲で繰り返すことができるのです。

実際に記述してみましょう。
次の例では「again関数」を定義し、その内部で処理のためにagain関数を使います。

again関数の機能としては、「if n > 0(引数nが0より大きい)」を条件に「return n + again(n – 1)」を出力するというものです。
if文の処理が実行されなかった場合には「return 0」を出力します。

仮に1以上の値を入れるとどうなるか試してみます。

【コード例】

#関数を定義
def again (n) :
    if n > 0:
        return n + again(n - 1) 
    return 0

#関数を実行して出力
print(again(6))

【出力結果】

21

この場合はif文の条件式の値がTrueとなるので、if文の処理が実行されます。
その結果、return値には繰り返すたびにn-1の値が加算されていきます。

その一方で、繰り返すごとにn自体の値は1つずつ減っていくので、
いずれはn=0になり、if文の条件を満たさなくなります。

その時点で処理が終了し、nの合計値が全体的な値として出力されるという仕組みです。
この例の場合は、入力値「6」から‐1した値を0になるまで繰り返し加算します。

6+5+4+3+2+1=21
このような計算が行われた結果、21が出力されているのです。

【コード例】

#関数を定義
def again(n): 
    if n > 0:
        return n + again (n - 1) 
    return 0

#関数を実行して出力
print(again(-3))

【出力結果】

0

ちなみに、引数の値が0以下だった場合はif文の処理は実行されず、
次の「return 0」の処理にスキップして、0が出力されます。

まとめ

冒頭でも書いたように、関数を味方につければ非常に頼れる「装備」になります。
難解で理解しがたい部分も多いですが、その分使いこなせるようになれば怖いものはありません。

関数の理解は、モジュール・パッケージなどさらに複雑な概念を理解することとも直結しています。
つまり、プログラミング学習をとてもスムーズに進められるようになるということ。

関数を本質的に理解すれば、多くの学習者が行き詰まる壁も難なく越えて行けるのです。

コメント

タイトルとURLをコピーしました