スキルアップ

Python入門:関数で処理の再利用、定義・引数・戻り値

はじめに

Pythonを学び手を動かしながらコードをたくさん書いていくと、
「このコード、何度も書いてるな」
と思う場面に出くわすことがあります。

例えば、

  • 計算処理
  • データの整形
  • バリデーション処理(入力チェック)

など、同じような処理が何度も出てくることがあります。

プログラミングを学び始めたばかりのころは、
何も考えずにコピペで対応してしまうことも多いです。

しかし、それでは気がつけばコードがどんどん長くなり、
どこで何をやっているのか分かりづらくなってしまいます。

そうした問題を解決してくれるのが、関数です。

関数を使えば、処理のまとまりに名前をつけて再利用でき、
同じコードを何度も書かなくて済みます。

また、関数はコードの見通しを良くし、
保守や変更にも強くなる
というメリットもあります。

今回は、私が学んで理解した関数の基本的な使い方から、
引数の工夫、戻り値の扱い、
関数の柔軟な使い方(ラムダ式や可変長引数など)までを、
順を追ってわかりやすく紹介していきます。

Pythonの学習を進める中で、
「関数」をしっかりと理解することは、
副業や実務で通用するスキルを身につける上で
避けては通れないステップ
です。

関数のポイントを押さえれば、
より整理されたコードを書けるようになります。

この記事はこんな方におすすめです!

  • Pythonを学びはじめたばかりで
    「関数って結局なんなの?」と感じている方
  • 引数や戻り値の使い方にまだ自信が持てない方
  • 実務や副業を見据えて、メンテナンス性の高い
    コードを書けるようになりたい方
  • 学習教材だけでなく、
    実際の使い方を具体例で知りたい方


第1章:そもそも関数とは

Pythonにおける「関数」とは、
ひとまとまりの処理に名前をつけて再利用可能にしたものです。

言い換えれば、ある入力に対して、決まった処理を行い、
結果を出す箱のようなものです。

Pythonのサンプルコードなどに使われている
print()input() も、
実はPythonに元から用意されている「組み込み関数」です。

つまり、関数を使うこと自体は
手を動かしてコードを書いていれば、

ほとんどの方がすでに経験済みのはずです。


関数を使うことで得られる3つのメリット

  • コードがスッキリ見やすくなる(可読性アップ)
    同じ処理を毎回書かなくて済むので、
    スッキリした構造になる
  • 変更に強くなる(保守性アップ)
    関数の中身だけを修正すれば、
    呼び出し側はそのままでOK
  • 何度も使える(再利用性アップ)
    必要なときに何度でも呼び出せるので効率的

関数を使わない場合の例:

# BMIの計算を3回やる例
height1 = 1.70
weight1 = 65
bmi1 = weight1 / (height1 ** 2)
print("BMI1:", bmi1)

height2 = 1.75
weight2 = 70
bmi2 = weight2 / (height2 ** 2)
print("BMI2:", bmi2)

height3 = 1.68
weight3 = 60
bmi3 = weight3 / (height3 ** 2)
print("BMI3:", bmi3)

このように、同じようなコードを繰り返していると、
見た目も見づらく可毒性が落ち、変更やミスの原因にもなります。


関数を使う場合の例:

def calc_bmi(height, weight):
    return weight / (height ** 2)

print("BMI1:", calc_bmi(1.70, 65))
print("BMI2:", calc_bmi(1.75, 70))
print("BMI3:", calc_bmi(1.68, 60))

このあと、関数の定義について紹介しますが
defキーワードを使って処理を関数化することで
コードの見通しがよくなり、再利用しやすい構造になります。

プログラミングにおいて、
「関数」はレシピや手順書のようなものです。

  • 材料(=引数)を受け取って
  • 決まった手順(=関数の中身)で処理し
  • 結果(=戻り値)として返す

レシピを一度作ってしまえば、
何度でも同じ料理を作れるようになるように
関数を作ってしまえば、
何度でも同じ処理を行うことが簡単になります。

これが、関数を使う最大の魅力です。


関数を使う場面の例

関数は次のような場面でよく使われます。

  • 計算処理
    (例:合計値、平均値、BMIなど)
  • データ変換
    (例:フォーマット整形、単位変換など)
  • 入出力処理
    (例:ファイル保存やデータ読み込み)
  • 繰り返し使うメッセージ出力など

今後、実務や副業でコードを書くようになると、
こうした処理のまとまりがたくさん出てきます。
関数を覚えておくことで、そうした処理を
スマートに再利用できるようになります。


第2章:関数の基本構文とreturnの使い方

Pythonにおける関数の基本構文

Pythonでは、関数を以下のように
defキーワードを使って定義します。

def 関数名(引数1, 引数2, ...):
    処理内容
    return 戻り値
  • def は「define(定義する)」の意味
  • :(コロン)で関数ブロックを開始
  • インデント(字下げ)で処理内容を記述
  • return で戻り値を指定(任意)

具体例:2つの数値を足して返す関数

def add(x, y):
    result = x + y
    return result

作成した関数を呼び出すときは、以下のように書きます。

total = add(5, 3) #add(5, 3)で呼び出し
print(total)  # → 8

returnの基本と戻り値の仕組み

return は、「この値を返します」と
関数の呼び出しもとに値を渡す役割を持っています。

def greet():
    return "こんにちは!"

message = greet()
print(message)  # → こんにちは!

上記のコードは、greet()関数の処理の結果が
変数messageに受け渡されています。

もし関数の定義で処理内の return を省略すると、
関数は None を返します。

def greet():
    x = 1 + 5 # returnはない

msg = greet()
print(msg)  # → None(greet()の戻り値)

関数の処理の結果を受け渡したい場合、
return を用いることを押さえましょう。

return を書かずに処理だけ行う戻り値なしの関数を作ることも
業務ではよく見られます。

「表示するだけ」「ファイルに書き出すだけ」などの処理の場合、
戻り値は不要になることも多いです。
関数の処理結果を関数の外でも利用したいかが
1つのポイントになります。


複数の値を返す:

Pythonでは return 文で複数の値をカンマ区切りで指定すると、
自動的にタプルとして返されます。

def calc(a, b):
    return a + b, a - b

result = calc(10, 3)
print(result)        # → (13, 7)
print(result[0])     # → 13
print(result[1])     # → 7

関数の戻り値がタプルとなる場合は、
受け取る変数側へアンパック代入をすることも可能です。

plus, minus = calc(10, 3)
print(plus)   # → 13
print(minus)  # → 7

補足:関数名の付け方

関数名は、「何をする関数なのか」
が伝わるようにするのがポイントです。

目的よい関数名例
合計を計算するcalculate_total()
あいさつを返すget_greeting()
BMIを算出するcalculate_bmi()
  • 複数の単語をつなげる場合は
    snake_case(スネークケース)を使います
  • 動詞から始まると関数らしくなります
    (例:print_, get_, send_ など)

第3章:引数の使い方

Pythonの関数を定義するとき、引数(ひきすう)を使うことで、
関数に外部の値を渡して処理の中で使うことができます。

引数として受け取る値を、呼び出しもとで変えてあげることで
関数内の処理構造は同じでも、
処理結果を可変として利用することができ
より柔軟なプログラムを作れるようになります。


位置引数とキーワード引数

位置引数(positional arguments)とは、
もっとも基本的な引数の渡し方で、
定義された順番に値を渡すスタイルです。

コードの例では、"太郎"が第一引数であるname
"おはようございます"が第二引数のmessageに受け渡されます。

def greet(name, message):
    print(f"{name}さん、{message}")

greet("太郎", "おはようございます")

出力結果:

太郎さん、おはようございます

キーワード引数(keyword arguments)とは、
引数名を指定して渡すことで、順番に関係なく指定できます。

greet(message="こんにちは", name="花子")

出力結果:

花子さん、こんにちは

位置引数とキーワード引数のポイントとして、
両方を混ぜて使う場合は、位置引数が先、キーワード引数が後
になるように記載しなければいけないことです。

greet("健太", message="こんばんは")  # OK
# greet(name="健太", "こんばんは")  # エラー

デフォルト引数

引数に初期値(デフォルト値)を設定することで、
呼び出し時に省略できるようになります。

def greet(name="ゲスト", message="こんにちは"):
    print(f"{name}さん、{message}")

greet()  # → ゲストさん、こんにちは
greet("太郎")  # → 太郎さん、こんにちは

デフォルト引数の定義時の注意点として、
デフォルト値を持つ引数は、
右端から連続して定義する必要があります。

# NG(エラーになる)
def greet(name="ゲスト", message):  

# OK
def greet(message, name="ゲスト"):

また、デフォルト引数に
リストや辞書などの変更可能(ミュータブル)な型を使うと、
予期せぬ共有が起きることがあります。

def append_item(item, lst=[]):
    lst.append(item)
    return lst

print(append_item("a"))  # → ['a']
print(append_item("b"))  # → ['a', 'b'] ← これは想定外!

これは変数の実際の値が受け渡されているわけではなく、
変数が格納されているメモリ番地が
共有されてしまうことが原因です。

このような、予期せぬ共有をしないための安全な書き方としては
Noneを使う方法があります。

def append_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

可変長引数(*args, **kwargs)

*args:位置引数をまとめて受け取ります。
(タプルとして受け取る)

def show_items(*args):
    for item in args:
        print(item)

show_items("りんご", "みかん", "バナナ")

出力結果:

りんご
みかん
バナナ

**kwargs:キーワード引数をまとめて受け取ります。
(ディクショナリとして受け取る)

def show_profile(**kwargs):
    for key, value in kwargs.items():
        print(f"{key}: {value}")

show_profile(name="たけし", age=30, hobby="筋トレ")

出力結果:

name: たけし
age: 30
hobby: 筋トレ

*** は引数に値を渡す際の
展開(アンパック)にも使えます。

リストを展開して渡す:

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

nums = [1, 2, 3]
print(add(*nums))  # → 6

ディクショナリを展開してキーワードとして渡す:

def introduce(name, age):
    print(f"{name}さんは{age}歳です")

info = {"name": "さゆり", "age": 28}
introduce(**info)

第4章:関数とスコープ(ローカル変数・グローバル変数)

プログラミングにおいて、スコープ(scope)とは、
変数が有効な範囲」のことです。

Pythonでは、同じ名前の変数であっても、
定義された場所によってアクセスできる範囲が異なります

これを理解しておかないと、関数内で意図しない動作をしたり、
思ったように値が更新されない原因となります。


ローカル変数

関数の中で定義された変数は「ローカル変数」と呼ばれ、
関数の外からはアクセスできません

def greet():
    message = "こんにちは!"  # ローカル変数
    print(message)

greet()           # → こんにちは!
# print(message)  # → エラー:message は外から見えない

このように、messagegreet() 関数の中でのみ有効です。


グローバル変数

関数の外で定義された変数は「グローバル変数」と呼ばれ、
全体で共有される変数です。

name = "太郎"  # グローバル変数

def greet():
    print(f"{name}さん、こんにちは!")

greet()  # → 太郎さん、こんにちは!

関数の中でグローバル変数を読み込むことは可能ですが
グローバル変数を関数内で変更したい場合は、
globalキーワードを明示する必要があります。

count = 0

def increment():
    count += 1  # エラーになる!
def increment2():
    global count
    count += 1

increment2()
print(count)  # → 1

上記のコードでエラーになる箇所では
UnboundLocalError になります。

なぜなら、Pythonは count += 1 を見たときに
countはローカル変数と判断し、
値がまだ存在しない変数に足そうとしてエラーになります。

global を使うと、関数の中からでも
外の変数に直接アクセス・更新できるようになります。

注意点としては、globalの使いすぎは
コードの複雑化を招くことです。

global は強力ですが、乱用すると
「どこで何が変更されたのかわかりづらい」
コードになってしまいます。

基本的には関数の戻り値で、
やり取りするほうが安全で読みやすい
です。


同じ名前の変数がある場合

x = 100  # グローバル変数

def test():
    x = 50  # ローカル変数(グローバルとは別)
    print("関数内のx:", x)

test()           # → 関数内のx: 50
print("グローバルのx:", x)  # → グローバルのx: 100

同じ名前の変数でも、スコープが違えば
完全に別物として扱われます。


第5章:関数の応用(ラムダ式・関数の代入)

関数の定義と使い方が分かってくると、

  • 関数を変数のように扱う
  • ちょっとした処理のために、
    わざわざ関数名をつけずに定義できれば便利

と感じる場面が出てきます。

そこで、Pythonでのテクニックとして、以下の2つを紹介します。

  • 関数を変数に代入して使う方法
  • 無名関数(ラムダ式)で
    シンプルな処理を書く方法

関数を変数に代入して扱う

Pythonでは、関数も「オブジェクト(=値)」
として扱えるので、変数に代入して使うことができます。

def greet(name):
    return f"{name}さん、こんにちは!"

say_hello = greet  # greet関数を代入
print(say_hello("太郎"))  # → 太郎さん、こんにちは!

この機能が役立つ場面として、

  • 複数の関数をリストやディクショナリで
    管理したいとき
  • コールバック関数として引き渡したいとき
    (後述する map()sorted() など)
def add(x, y): return x + y
def sub(x, y): return x - y

func_dict = {"加算": add, "減算": sub}
print(func_dict["加算"](10, 3))  # → 13

ラムダ式(lambda)

Pythonには、lambda を使って
名前をつけずに定義できる関数(無名関数)があります。

# 普通の関数
def square(x):
    return x * x

# ラムダ式(無名関数)
square_lambda = lambda x: x * x

print(square_lambda(5))  # → 25

ラムダ式の定義は、以下です。
def を使う関数よりも
「1行で完結できる処理」に使うのがベターです。

lambda 引数: 戻り値の式

map() × ラムダ式

nums = [1, 2, 3, 4]
squared = list(map(lambda x: x**2, nums))
print(squared)  # → [1, 4, 9, 16]

ここでは map() 関数を使って、各要素にラムダ式で定義した関数(x を 2 乗する)を適用しています。


sorted() × ラムダ式

data = [("太郎", 25), ("花子", 22), ("健太", 30)]

# 年齢順にソート
sorted_data = sorted(data, key=lambda x: x[1])
print(sorted_data)
# → [('花子', 22), ('太郎', 25), ('健太', 30)]

ラムダ式と関数の使い分け

タイミングおすすめの書き方
一時的な処理ラムダ式(lambda)
複数行にまたがる処理普通の関数(def)
何度も使う処理普通の関数(def)

第6章:関数のドキュメンテーション

関数を他の人と共有したり、あとで自分が見返したりする際に
「この関数は何をするのか?」
がすぐにわかるようにしておくことは、とても大切です。

そこで使われるのが
ドキュメンテーション文字列(docstring) です。


ドキュメンテーション文字列

関数の定義直後に書く文字列で、
関数の目的や使い方を説明するためのメモ書きのようなものです。

def greet(name):
    """名前を受け取って、あいさつ文を返す関数"""
    return f"{name}さん、こんにちは!"

このように、関数の最初に
""" 三連引用符 """ で囲んで記述します。


ドキュメンテーションの参照

記述したドキュメンテーション文字列は、
関数名.__doc__ であとから取り出すことができます。

print(greet.__doc__)
# → 名前を受け取って、あいさつ文を返す関数

これは Jupyter Notebook や
Pythonの組み込みhelp() 関数でも表示される情報です。

docstringのポイントとして、

  • 三連引用符(""")で囲んで、関数の直後に記述
  • 関数の目的・引数・戻り値を明記すると親切
  • VSCodeやJupyter Notebookでは、
    この情報が自動補完に表示されることも
  • チーム開発や副業の実務でも
    「読めるコード」の第一歩になる

第7章:まとめ&次回予告

今回は、Pythonにおける関数の基本を中心に一通り学んできました。

  • 関数とは、処理のまとまりを部品化して
    再利用できる仕組み
  • def 文による関数定義と
    return を使った値の返却方法
  • 引数には位置・キーワード・デフォルト・可変長
    など多彩な指定方法がある
  • 変数のスコープ(ローカル・グローバル)と
    global の使い方
  • ラムダ式や関数の代入による柔軟な関数活用
  • 関数に説明をつける docstring によって、
    読みやすく保守性の高いコードへ

関数は、Pythonにおける重要テーマの1つであり、
実務や副業案件でも頻繁に活用されます。

次回は「オブジェクトとクラス定義」について
まとめていく予定です。

関数が処理のまとまりを表すのに対し、
クラスやオブジェクトは「データ+処理」を
まとめて管理できる仕組み
です。

  • クラスってなに?オブジェクトってどう違うの?
  • __init__ メソッドや self の意味とは?
  • 自作クラスの作り方と使い方は?

など、いよいよ「オブジェクト指向」と呼ばれる
プログラミングの考え方の入り口に立ちます。

▶次回の記事はこちら:
[現在準備中です!少々お待ちください!]

-スキルアップ