テクノロジー

2023年1月1日

Python入門7 関数化

関数化が行えるようになる

関数化

ここまでは用意された関数(組み込み関数)を使うだけでしたが、独自の関数を作ることが可能です。まとまりのある箇所は関数化しておくと、再利用できるようになり便利です。

関数の定義

関数を定義する時には、defを使います。defはPythonの予約語です。関数の処理であることを示すためにはインデントを使います。

以下が関数を使ったプログラムの例です。

def print_hello_world():
  print("Hello, World!")

実行しても何も表示されませんが、関数を定義することができています。関数を使ってみます。

print_hello_world()

実行すると「Hello, World!」と表示されます。「Hello, World!」と表示する、print_hello関数を作ったことになります。

《関数の名前の付け方》

関数は変数同様に大文字小文字のアルファベット、数字、アンダースコア(_)が使えます。数字からはじまる名前や、予約語と同じ名前にはできません。

推奨される命名も「アルファベットは小文字のみを使い、単語間をアンダースコア(_)で区切る方法」で、変数と同じです。

引数

関数には 引数 を渡すこともできます。次のように括弧の中に 仮引数 名を書くことで、関数内でその仮引数を使うことができます。関数を呼び出す時には括弧の中に 実引数 となる値を書き入れます。

「World」の部分を他の単語に変えられるようにしてみます。

def print_hello_something(something):
  print("Hello, {}!".format(something))

print_hello_something("Python")

実行すると「Hello, Python!」と表示されます。

引数は複数渡すこともできます。「!」の部分を変えられるようにしてみます。

def print_hello_something(something, end):
  print("Hello, {}{}".format(something, end))

print_hello_something("Python", "?")

実行すると「Hello, Python?」と表示されます。

また、デフォルトの値を決めることもできます。仮引数の後に=を使って設定します。この書き方をする引数を キーワード引数 と呼びます。キーワード引数ではない引数は、 位置引数 と呼びます。キーワード引数は位置引数よりも後ろに書く必要があります。

def print_hello_something(something, end = "!"):
  print("Hello, {}{}".format(something, end))

print_hello_something("Python")
print_hello_something("Python", end = "?")

実行すると「Hello, Python!」「Hello, Python?」と表示されます。実引数でendを書かなかった場合、デフォルトの「!」が表示されています。

位置引数は必ず順番通りにすべて書く必要があり、一方キーワード引数は位置引数より後ろに必要に応じて書き加えます。

戻り値

呼び出した関数から何かしらの値(戻り値)を受け取ることもできます。return を使います。

def hello_something(something, end = "!"):
  return "Hello, {}{}".format(something, end)

print(hello_something("Python", end = "!!"))

実行すると「Hello, Python!!」と表示されます。

このように、関数の中でprint関数で出力を行うよりも、戻り値を受け取ってから出力するようにした方が、使い勝手が良いプログラムとなります。

ここまでは文字列で見てきましたが、数値型であれば次のようなプログラムが作れます。

def sample_function(x, y):
  answer = (x+y) * 2
  return answer

print(sample_function(3, 5))
print(sample_function(10, 3))
print(sample_function(-20, -10))

これは以下のプログラムと同じ結果になりますが、同じ形の計算を繰り返すのであれば、関数にした方が便利です。

print((3+5) * 2)
print((10+3) * 2)
print((-20+(-10)) * 2)

なお、関数内の変数は戻り値に指定しない限り、関数の外で使用することができないことに注意が必要です。

*以下はエラーになる例です。

def sample_function2(x, y):
  answer1 = (x+y) * 2
  answer2 = answer1 + 10
  return answer1

print(sample_function2(3, 5))
print(answer2) # NameErrorになる

この例で関数内で定義されたanswer2は、関数の外では定義されていないため、NameError: name 'answer2' is not definedというエラーが表示されます。

answer1とanswer2両方使いたい場合は、戻り値をタプルにすることで、複数の値を渡します。

*以下がエラーを解消した例です。

def sample_function3(x, y):
  answer1 = (x+y) * 2
  answer2 = answer1 + 10
  return answer1, answer2

answer1, answer2 = sample_function3(3, 5)
print(answer1)
print(answer2)

関数化の例

条件分岐のテキストで、if文の例として以下のようなプログラムを挙げました。

ADULT_AGE = 20

student_name = "Alice"
student_age = 19
if student_age < ADULT_AGE:
    print("{}は{}歳未満です。".format(student_name, ADULT_AGE))
else:
    print("{}は{}歳以上です。".format(student_name, ADULT_AGE))

この一部を関数化すると、次のようにすることができます。

なお、ダブルクォーテーション3つで囲われた範囲は コメントアウト です。コメントアウトの範囲は実行されないため、メモとして使うことができます。関数の概要、引数が何か、戻り値が何かを書いてあります。また、#の後ろもコメントアウトです。こちらもメモとして使うことができます。

ADULT_AGE = 20 # 成人年齢

def text_adult_age(personal_age, adult_age = 20):
  """
  成人年齢を超えているかどうかの文字列を返す。

  Parameters:
  ------------
  personal_age : int
    判定したい人の年齢
  adult_age : int (default : 20)
    成人年齢。デフォルトで20歳。

  Returns:
  ------------
  str
    adult_age以上、未満という文字列
  """
  if personal_age > adult_age:
    return "{}歳以上".format(adult_age)
  else:
    return "{}歳未満".format(adult_age)

# 学生の情報
student_name = "Alice"
student_age = 19

print("{}は{}です".format(student_name, text_adult_age(student_age, adult_age = ADULT_AGE)))

全体としては説明なども加わったため長くなっていますが、出力部分はすっきりとしました。「20歳以上」、「未満」という表示をいろいろな箇所で使いたい場合は関数化しておくと便利です。また、関数化した方が意味が分かりやすくなるという場合もあります。

参考文献

はじめに — pep8-ja 1.0 ドキュメント

4.6. 関数を定義する — Python 3.7.3 ドキュメント

DIVE INTO CODEのことをもっと知ってみませんか?