【Python】defとは?関数の定義と実行方法をわかりやすく解説

はじめに

プログラミングを始めるうえで、最初に戸惑いやすいのが「関数」の概念ではないでしょうか。
Pythonでは、関数を定義するために def キーワードが利用されます。
これはプログラミングの初心者でも理解しやすい記述ができ、読みやすいコードを書くための重要な仕組みです。

関数を使いこなせるようになると、何度も繰り返す処理を1か所にまとめたり、プログラムを見通しよく整理することができます。
たとえば、エクセルのマクロをイメージするとわかりやすいかもしれません。
繰り返し同じ作業をする場合、関数としてひとまとまりにすることで効率化が図れます。

この記事では、 def というキーワードそのものの意味や用途に加え、引数や戻り値、ローカル変数とグローバル変数の違いなどについて詳しく説明します。
実務の観点からも役立つ内容にしていきますので、これからPythonを学ぼうという皆さんにとって、参考になるはずです。

この記事を読むとわかること

  • def キーワードの基本的な役割と使い方
  • 関数を使うメリットと実務での具体的な活用シーン
  • Python関数の構文と命名ルール
  • 引数や戻り値の扱い方、複数の戻り値の返し方
  • ローカル変数とグローバル変数の違い
  • 初心者がつまずきやすいポイントの対処法

ここからは順を追って解説していきます。
読み終えるころには、自信を持ってPythonで関数を扱えるようになるはずです。

【前提】関数とは何か?

関数とは、複数の処理をひとまとめにするしくみです。
「ある入力を与えると、何らかの結果が返ってくる」イメージを持つと理解しやすいでしょう。
たとえば電卓を思い出してみてください。
数字を入力して「+」や「×」の演算ボタンを押すと、最終的に答えが表示されます。
これをプログラムの世界で再現したものが関数です。

関数を使うと、以下のようなメリットがあります。

  • 同じ処理を何度でも再利用できる
  • 処理内容をひとまとまりにでき、コードが読みやすくなる
  • バグを修正するときでも、関数単位で見直すので効率化できる

こうしたメリットから、プログラミング実務では関数が頻繁に用いられます。
特にチーム開発では、わかりやすい関数名や用途別の関数を作ることが、後からコードを読む人への配慮にもつながります。

Python def:関数の定義と実行

Python関数の定義:def

Pythonで関数を定義するときは、行の先頭に def を書き、その後に関数名と括弧を置きます。
さらにコロン「:**」を記述し、次の行にインデントを下げて関数の処理を並べるのが基本形です。
イメージとしては以下のようになります。

def 関数名(引数1, 引数2, ...):
    # 関数内の処理
    return 戻り値

このとき、Pythonはインデント(空白スペース)に厳密です。
関数内の処理を示す部分は、必ずスペース4つ分などで下げて記述します。
このインデントが合っていないと、構文エラーが発生しますので注意してください。

Python:関数の命名ルール

関数名には、わかりやすい名前をつけることが大事です。
Pythonの一般的なスタイルガイド(PEP 8)では、関数名はすべて小文字で書き、単語の区切りにはアンダースコア _ を使うと推奨されています。
たとえば calculate_sum のように、動作が推測しやすい名前にすると良いでしょう。
基本的には以下のような命名を意識します。

  • 先頭に数字を使わない(NG例: 1st_function
  • 特殊文字は極力使わない(NG例: my-function
  • 目的や処理の内容を想起できる名前を選ぶ

命名規則を守っておくと、同僚や他の開発者がコードを読んだときに混乱を避けやすくなります。
また、自分自身も時間が経ってからコードを読み返すときに理解しやすくなるはずです。

Python関数の実行

定義した関数を使うには、関数名を呼び出すだけです。
Pythonでは、関数名に括弧 () をつけて、必要に応じて引数を渡します。
たとえば calculate_sum(5, 10) のように書くと、先ほどの例に当てはめれば、合計値が返ってくるイメージです。

def greet_user(name):
    print("Hello, " + name + "!")

# 関数の実行例
greet_user("Alice")

上記のコードでは、呼び出し時に "Alice" を引数として渡しています。
そうすると Hello, Alice! と出力される仕組みです。
このように引数を渡して関数を実行するのがPythonの基本的な流れになります。

Python:関数の '引数' と '戻り値'

関数が受け取るデータを 引数、関数が返すデータを 戻り値(または返り値)と呼びます。
引数を受け取って計算や処理を行い、最終的に戻り値を返す、という流れがよく見られるパターンです。
この仕組みを使うと、同じ処理を何度も再利用できるので便利です。

関数に引数を渡さないパターンもあります。
その場合は () の中を空にして書きます。
また、戻り値を返さない関数も定義できます。
その場合は return 文を使わず、単に処理だけを行うことがあります。
例えば、画面に文字を表示するだけの関数などが当てはまります。

引数と戻り値:サンプルコード

例として、二つの数字を受け取り、合計を戻り値として返す関数を考えてみましょう。

def add_numbers(a, b):
    total = a + b
    return total

# 関数を実行する
result = add_numbers(3, 7)
print(result)  # 10が出力される

このように、 return 文を使うと、 add_numbers 関数が戻り値を返してくれます。
呼び出し側ではその戻り値を変数 result に受け取り、最後に print で表示する仕組みです。
実務での開発では、戻り値を受け取って次の処理に回すケースがよくあります。

Python関数:引数の指定方法

Pythonには、引数を指定するいくつかの方法があります。
初心者の方は、まず 位置引数 から覚えると良いでしょう。
それ以外にも キーワード引数デフォルト引数可変長引数 などが存在し、複雑な処理をシンプルにまとめるのに役立ちます。

Python関数:位置引数

位置引数とは、関数を呼び出すときに 引数の順番 で値が割り当てられる仕組みです。
たとえば下記のように namegreeting を受け取る関数があった場合、呼び出し側での順番が非常に重要です。

def greet_user(name, greeting):
    print(greeting + " " + name + "!")

# 位置引数の例
greet_user("Alice", "Hello")  # Hello Alice!
greet_user("Bob", "Hi")       # Hi Bob!

上記の関数では、最初の引数が name、2番目の引数が greeting として割り当てられます。
もし順番を逆にして greet_user("Hello", "Alice") と書いた場合、期待した結果と異なる表示になってしまうので注意が必要です。

Python関数:キーワード引数

キーワード引数では、引数の名前を明記して指定できます。
これによって、引数の順番に依存しない呼び出し方が可能です。

def greet_user(name, greeting):
    print(greeting + " " + name + "!")

# キーワード引数の例
greet_user(name="Charlie", greeting="Good morning")  # Good morning Charlie!
greet_user(greeting="Welcome", name="Diana")         # Welcome Diana!

こうすることで、引数が多い関数や引数の順番を気にしたくないケースでも、呼び出しがわかりやすくなります。
また、コードを読むときに「どの値がどの引数に当たるのか」が一目でわかります。

Python関数:デフォルト引数

デフォルト引数は、あらかじめ引数に初期値を設定しておく方法です。
関数を呼び出すときに、その引数を省略した場合はデフォルト値が使われます。

def greet_user(name, greeting="Hello"):
    print(greeting + " " + name + "!")

# デフォルト引数の例
greet_user("Eve")                # Hello Eve!  (greetingを省略)
greet_user("Frank", "Welcome")   # Welcome Frank!

このように、 greeting を渡さなかった場合は "Hello" が使われます。
必要に応じてカスタマイズできる一方、意図しないデフォルト値を設定しないように注意が必要です。
デフォルト引数を複数設定することも可能ですが、その分わかりにくくなる場合もあるため、使い方には気を配りましょう。

Python関数:可変長引数

関数を定義するとき、引数の数が固定ではなく、不定の数を受け付けたい場合があります。
例えば、合計値を計算するときに、2つだけでなく3つや4つなどの数字も渡したいケースです。
この場合、可変長引数 *args や、キーワード付きの可変長引数 **kwargs が利用できます。

def sum_numbers(*args):
    total = 0
    for num in args:
        total += num
    return total

print(sum_numbers(1, 2, 3))       # 6
print(sum_numbers(4, 5, 6, 7))    # 22

引数にアスタリスク * をつけると、渡された値がタプルとして受け取れます。
これにより、引数の数を決め打ちしなくても済むわけです。
実務でも、ログをまとめて出力するときや、不定のオプションを受け付ける処理を書くときに重宝します。

例えば、Webアプリケーションで複数のパラメータを受け取るAPIを作成する場面でも、可変長引数によって汎用的な処理が可能になります。

複数の戻り値を設定する方法

Pythonでは、複数の値を一度に返すことができます。
具体的には、カンマ区切りで複数の要素を return すれば、タプルとして返却されるのです。
たとえば下記の例を見てみましょう。

def get_user_info():
    name = "Alice"
    age = 30
    location = "Tokyo"
    return name, age, location

user_name, user_age, user_location = get_user_info()
print(user_name)      # Alice
print(user_age)       # 30
print(user_location)  # Tokyo

ここでは name, age, location がタプルとして返されます。
呼び出し側で複数の変数を一度に受け取れるので、とても便利な書き方です。
実務でも、たとえばデータベースから複数の値を取得するときや、計算の途中で異なる種類の結果を返したいときなどに活用できます。

ローカル変数とグローバル変数の違いは?

Pythonでは、関数の中で定義した変数は ローカル変数 として扱われ、関数の外で定義された変数は グローバル変数 と呼ばれます。
ローカル変数は関数の実行が終わると参照できなくなり、グローバル変数はどの関数からでも参照が可能です。

x = 10  # グローバル変数

def sample_function():
    x = 5  # ローカル変数
    print(x)  # 5が表示される

sample_function()
print(x)      # 10が表示される

この例では、関数内の x と関数外の x は別物として管理されます。
したがって、関数内で x を変更しても、外側の x の値は影響を受けません。
実務でグローバル変数を多用すると、デバッグが難しくなるため推奨されないことが多いです。
なるべく関数内部だけで完結するローカル変数を使うようにすると、コードの保守性が高まります。

関数の実務活用シーン

ここまでで、Pythonの関数の基本や引数・戻り値の扱い方などをご紹介しました。
次に、実務でどのように活用できるか、その一例を挙げてみましょう。

例えば、以下のようなシーンが考えられます。

  • データのバリデーション:ユーザーが入力したデータをチェックし、不正な値なら警告を返す。
  • 繰り返し処理:同じ処理を定期的に行うスクリプトの作成。
  • 複雑なロジックの切り出し:ビジネスロジックを関数としてまとめ、見通しをよくする。

他にも、Webフレームワークを使うときは、データベースアクセス用の関数や画面表示のための関数を分けることが多いです。
関数を適切に分割すれば、あとから仕様変更があっても修正範囲を限定しやすくなります。

関数の戻り値がない場合はどうなる?

戻り値を return しない場合、Pythonの関数は None を返します。
意図して return None と書かなくても、実行の結果としては何も返さないという扱いになるのです。

def do_something():
    print("Processing...")

result = do_something()
print(result)  # Noneと表示される

こうした処理は、特定の計算結果を返す必要がないときに使われます。
画面表示だけを行う、ファイルへの書き込みを行うなど、手続き的な処理でよく見られます。
実務では、エラーチェックを兼ねて「本当に戻り値は必要ないか」を考えてコードを書くといいでしょう。

関数のスコープと注意点

スコープとは、変数や関数が有効になる範囲のことです。
Pythonの場合、関数内で変数を定義すると、その変数は関数の外には影響しません。
これはローカル変数とグローバル変数の話と絡んできますが、基本的には 関数内の変数は関数内だけ で完結するように書く方が安全です。

どうしても関数外の変数を変更したい場合は、 global 文を使うことができます。
ただし、これはコードの可読性や保守性を下げる一因となるので、やむを得ない場合を除いては避けるのが一般的です。
複数の関数やファイルから同じ変数を参照するケースが多いと、バグが発生したときに原因追及が難しくなるため注意してください。

実務で使う際のエラー処理

実務では、関数を呼び出したときに想定外のデータが来ることがあります。
その場合は、適切なエラー処理や例外処理を行うことが大事です。
たとえば、引数が数字以外の値であれば ValueError を発生させてエラーとして扱う、といった方法が考えられます。

def divide(a, b):
    if b == 0:
        raise ValueError("分母が0です")
    return a / b

try:
    result = divide(10, 0)
    print(result)
except ValueError as e:
    print("エラーが発生しました:", e)

ここでは、分母が0の場合に ValueError を発生させ、その後の処理でキャッチしています。
このように関数の中でエラーの検出と発生を行い、呼び出し側で例外をキャッチして対処するパターンがよく使われます。
実務では外部APIとの通信やファイル操作など、予期せぬエラーが起きる可能性があるため、適切なエラー処理を設計するのが重要です。

無名関数(ラムダ式)との違い

Pythonには、 def を使わずに短い関数を定義する ラムダ式 という方法もあります。
lambda キーワードを使うため、ラムダ関数と呼ばれることが多いです。
ただしラムダ式は単一の式しか書けないため、複雑な処理には向きません。

# ラムダ式の例
square = lambda x: x * x
print(square(5))  # 25

ラムダ式は使いこなすと便利ですが、明確な処理のまとまりを表すなら、やはり def を使うほうが可読性が高いケースが多いです。
実務でも、簡潔なデータ変換や短い比較処理などにはラムダ式、より大きなロジックには def と使い分けをする場合が多いでしょう。

テストコードでの利用

品質を高めるためにテストコードを整備するのは、実務ではほぼ必須です。
関数単位でテストを書くことで、コードがきちんと意図した通りに動いているか確認できます。
たとえば下記のように、テスト用のスクリプトで関数を呼び出すだけでOKです。

import unittest

def add_numbers(a, b):
    return a + b

class TestAddNumbers(unittest.TestCase):
    def test_add_numbers(self):
        self.assertEqual(add_numbers(2, 3), 5)
        self.assertEqual(add_numbers(-1, 1), 0)

if __name__ == "__main__":
    unittest.main()

テストを実行することで、もし将来コードを修正したときに意図しない挙動になっていないかを検知できます。
特に引数が多い関数や戻り値が複数ある関数では、テストをきちんと整備しておくと開発効率が上がるでしょう。

関数ドキュメンテーションのすすめ

関数をたくさん定義すると、どこかで「この関数は何をするのか?」といった混乱が生じることがあります。
そこでおすすめなのが、 関数の先頭にドキュメンテーション文字列 (docstring) を書くこと です。 Pythonでは三重引用符 """ ... """ で囲むと、関数の説明文を定義できます。

def multiply(a, b):
    """
    2つの数値を受け取り、その積を返す関数。
    a: 数値
    b: 数値
    戻り値: aとbの積
    """
    return a * b

このdocstringは、VS Codeなどのエディタや自動ドキュメント生成ツールで利用され、関数の使い方を可視化するのに役立ちます。
また、時間が経ってから見返す際にも非常に助けになりますので、実務でも積極的に記述するよう心がけましょう。

まとめ

ここまで、Pythonの def キーワードを使った関数の定義や実行方法、引数や戻り値の扱い方から実務での活用シーンまで幅広く解説しました。
初心者の皆さんがまず抑えるべきポイントを整理すると、以下のようになります。

  • def を使って関数を定義し、 () の中に引数を指定する
  • 関数内ではインデントを正しく揃え、行の先頭に戻してから次の処理を書く
  • return 文で戻り値を返す場合と、返さない場合がある
  • 引数には位置引数・キーワード引数・デフォルト引数・可変長引数など、多様なパターンがある
  • ローカル変数とグローバル変数の扱いを理解し、極力グローバル変数を使わないようにする
  • 実務ではエラー処理やテストコードの整備、docstring を使ったドキュメント化が重要

これらの点を意識しながらコードを書くと、可読性が高く保守しやすいプログラムを作れるはずです。
関数は今後のPython学習や実務に欠かせない概念なので、繰り返し練習して身につけてみてください。

Pythonをマスターしよう

この記事で学んだPythonの知識をさらに伸ばしませんか?
Udemyには、現場ですぐ使えるスキルを身につけられる実践的な講座が揃っています。