はじめに
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 は外から見えない
このように、message
は greet()
関数の中でのみ有効です。
グローバル変数
関数の外で定義された変数は「グローバル変数」と呼ばれ、
全体で共有される変数です。
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
の意味とは?- 自作クラスの作り方と使い方は?
など、いよいよ「オブジェクト指向」と呼ばれる
プログラミングの考え方の入り口に立ちます。
▶次回の記事はこちら:
[現在準備中です!少々お待ちください!]