関数とモジュール——コードに名前を付け、組み合わせる
レッスン5:関数とモジュール——コードに名前を付け、組み合わせる
このレッスンで学ぶこと
- 関数の発想(操作に名前を付け、繰り返し使う)を理解する
defでの関数定義、引数と戻り値の書き方を身につける- デフォルト引数とキーワード引数を理解する
- ローカル変数とグローバル変数のスコープの違いを把握する
- 複数の関数を組み合わせて 1 つの業務を表現する
importでモジュールを読み込み、標準ライブラリの代表選手(math・random・datetime・os・pathlib)を活用する
前回のレッスンで、リスト・タプル・辞書・集合の 4 つのデータ構造を扱いました。データを表現する手段がそろってきたところで、次の課題は「処理に名前を付ける」「処理を組み合わせる」ことです。本レッスンでは、関数とモジュールという、コードを構造化する 2 つの基本道具を扱います。
関数の発想
関数は「操作に名前を付けて、何度でも呼び出せるようにする」道具です。Excel の関数(SUM、IF、VLOOKUP など)の発想に近く、入力(引数)を渡すと結果(戻り値)が返ってきます。
関数を使う 3 つの利点
- 再利用:同じ処理を何度も使い回せる
- 読みやすさ:処理に名前が付くので、コードが文章のように読める
- 保守性:修正箇所が 1 つに集約され、変更が楽
Python の組み込み関数(復習)
これまでに、すでにいくつかの組み込み関数を使ってきました。
print("Hello") # 表示
len("Python") # 文字数を数える
sum([1, 2, 3]) # 合計
type(5) # 型を調べる
int("30") # 型変換
これらは Python に最初から組み込まれている関数です。本レッスンでは、これらに加えて、自分で関数を定義する方法を学びます。
💡 ポイント 関数は「操作に名前を付け、何度でも呼び出せる」道具で、再利用・読みやすさ・保守性の 3 つの利点があります。
len・sum・type・intなどはすでに使ってきた組み込み関数です。
関数の定義——def
自分で関数を定義するときは、def という予約語を使います。
最小の関数
def greet():
print("こんにちは")
greet() # こんにちは
def の後ろに関数名、( ) で引数を囲み、: で終え、字下げしてブロックに処理を書きます。greet() と書いて関数を呼び出します。
引数を取る関数
def greet(name):
print(f"こんにちは、{name}さん")
greet("山田") # こんにちは、山田さん
greet("鈴木") # こんにちは、鈴木さん
name が引数(パラメータ)です。呼び出すときに渡した値("山田")が、関数内で name として使われます。
戻り値を返す関数——return
def add(a, b):
return a + b
result = add(3, 4)
print(result) # 7
return は「関数の中で計算した結果を、呼び出し元に返す」予約語です。return を使った関数は、Excel の関数のように「呼び出すと値が戻ってくる」形になります。
return がない関数
return を書かない関数は、None を返したのと同じになります。
def show(message):
print(message)
result = show("Hello") # Hello が表示される
print(result) # None
show は画面に表示するだけで、戻り値はありません。
複数の値を返す
タプルを使うと、複数の値を一度に返せます。
def calc(a, b):
total = a + b
diff = a - b
return total, diff
t, d = calc(10, 3)
print(t) # 13
print(d) # 7
「関数の戻り値はタプル」「呼び出し側でアンパック(分けて受け取る)」という発想です。
💡 ポイント 関数は
def 関数名(引数):で定義し、returnで値を返します。複数の値を返すときはタプルでまとめて、呼び出し側でアンパックします。
デフォルト引数とキーワード引数
関数の引数には、便利な書き方が 2 つあります。
デフォルト引数
引数に「指定しなかったときの値」を設定できます。
def greet(name, prefix="こんにちは"):
print(f"{prefix}、{name}さん")
greet("山田") # こんにちは、山田さん
greet("鈴木", "おはよう") # おはよう、鈴木さん
prefix="こんにちは" がデフォルト値です。呼び出し時に省略すると、このデフォルト値が使われます。
キーワード引数
呼び出し時に、引数名を指定して渡せます。
def order(product, quantity, price):
print(f"{product} を {quantity} 個、{price} 円で発注")
order(product="リンゴ", quantity=10, price=200)
order(quantity=5, product="ミカン", price=150) # 順番を気にしなくてよい
引数が多いとき、キーワード引数を使うと「どの引数に何を渡しているか」が明確になります。業務スクリプトでは、引数 3 つ以上のときにキーワード引数を使うのが推奨です。
💡 ポイント デフォルト引数で「指定しなかったときの値」を設定でき、キーワード引数で「引数名を指定して渡す」ことができます。引数が多い関数は、キーワード引数で呼び出すと読みやすくなります。
スコープ——変数の「届く範囲」
関数の中で定義した変数と、関数の外の変数は別物です。これを「スコープ」(届く範囲)と呼びます。
ローカル変数
関数の中で代入した変数は、関数の中だけで通用する「ローカル変数」です。
def calc():
total = 100 # ローカル変数
print(total)
calc()
# print(total) # NameError:関数の外では使えない
グローバル変数
関数の外で定義した変数は、関数の中からも読めます(「グローバル変数」と呼びます)。
tax_rate = 0.1 # グローバル変数
def with_tax(price):
return int(price * (1 + tax_rate)) # 読むのは OK
print(with_tax(1000)) # 1100
関数の中でグローバルを書き換える
関数の中でグローバル変数を「書き換え」たいときは、global 宣言が必要です。
counter = 0
def increment():
global counter
counter = counter + 1
increment()
increment()
print(counter) # 2
ただし、global を多用するコードは読みにくくなります。本コースの推奨は、必要な値は引数で受け取り、戻り値で返す、というスタイルです。
スコープを意識する利点
ローカル変数の発想を理解すると、関数同士が「他人の変数を勝手に変えない」ように書けます。これが、関数を組み合わせるときの安心感を支えます。
💡 ポイント 関数内で代入した変数はローカル(関数内だけ)、関数外で定義した変数はグローバル。関数の中でグローバルを書き換えるには
global宣言が必要ですが、引数と戻り値でやり取りするスタイルの方が読みやすくなります。
複数の関数を組み合わせる
業務スクリプトでは、1 つの大きな処理を複数の小さな関数に分けて書きます。
例:売上集計
def total_sales(prices):
return sum(prices)
def average_sales(prices):
if len(prices) == 0:
return 0
return total_sales(prices) / len(prices)
def report(name, prices):
total = total_sales(prices)
average = average_sales(prices)
print(f"{name}:合計 {total} 円、平均 {int(average)} 円")
# 使う
report("4 月の売上", [1000, 1500, 800, 2200, 1800])
# 4 月の売上:合計 7300 円、平均 1460 円
3 つの関数(total_sales、average_sales、report)に分けたことで、それぞれの役割が明確になり、テストや修正もしやすくなりました。
「1 つの関数は 1 つの仕事」の原則
業務での関数設計の基本は「1 つの関数は 1 つの仕事」です。1 つの関数が 50 行・100 行と長くなったら、複数の関数に分けるサインです。逆に、3 行・5 行で済む関数を分けるのは、過剰になりがちです。実務上は、「20 行を超えたら分割を検討」あたりが目安です。
💡 ポイント 業務スクリプトは「1 つの関数は 1 つの仕事」を意識し、複数の関数を組み合わせて全体を作ります。20 行を超える関数は分割を検討します。
モジュールと import
Python の強みである「大きなエコシステム」を活かすには、ほかの人が作った機能を「モジュール」として読み込んで使う必要があります。
import の基本
import math
print(math.sqrt(16)) # 4.0
print(math.pi) # 3.141592653589793
import math で math モジュールを読み込み、math.sqrt(16) で機能を呼び出します。
from … import …
特定の機能だけを取り出して使うこともできます。
from math import sqrt, pi
print(sqrt(16)) # 4.0
print(pi) # 3.141592653589793
これを使うと、math. を毎回書かずに済みます。ただし、ほかの場所でも sqrt を使っているなど名前が衝突しそうなときは、import math の形のほうが安全です。
import as——別名を付ける
長いモジュール名には、短い別名を付けるのが慣習です。
import pandas as pd # 業界の慣習
import numpy as np # 業界の慣習
pandas は pd、numpy は np で呼ぶのが定番です。本コースのレッスン 7 でも pandas を使うときに pd を使います。
💡 ポイント モジュールは
import モジュール名で読み込み、モジュール名.機能名で使います。from … import …で特定機能だけ取り出すこともでき、import … as …で別名を付けるのも慣習です。
標準ライブラリの代表選手
Python には「標準ライブラリ」と呼ばれる、最初から付いてくるモジュール群があります。本コースで覚えておきたい 5 つを紹介します。
math——数学関数
import math
print(math.sqrt(2)) # 1.4142135623730951(平方根)
print(math.floor(3.7)) # 3(切り捨て)
print(math.ceil(3.2)) # 4(切り上げ)
print(math.log10(1000)) # 3.0(常用対数)
print(math.pi) # 3.141592653589793(円周率)
random——乱数
import random
print(random.random()) # 0.0 以上 1.0 未満のランダムな小数
print(random.randint(1, 6)) # 1 から 6 までのランダムな整数(サイコロ)
print(random.choice(["A", "B", "C"])) # リストからランダムに 1 つ
業務では、サンプリング、シャッフル、初期値のランダム化などで使います。
datetime——日付と時刻
from datetime import datetime, date, timedelta
now = datetime.now()
print(now) # 例:2026-06-20 14:30:00.123456
today = date.today()
print(today) # 例:2026-06-20
tomorrow = today + timedelta(days=1)
print(tomorrow) # 例:2026-06-21
# 文字列にフォーマット
print(now.strftime("%Y 年 %m 月 %d 日")) # 例:2026 年 06 月 20 日
業務での日付計算(N 日後、月初、月末、営業日カウント)に必須のモジュールです。
os——OS との連携
import os
print(os.getcwd()) # 現在の作業ディレクトリ
print(os.listdir()) # 現在のフォルダ内のファイル一覧
ファイルやフォルダの操作で使います。最近では、後述の pathlib の方が読みやすいため、os は補助的に使うのが流れです。
pathlib——モダンなパス操作
pathlib は、ファイルパスをオブジェクトとして扱えるモジュールです。Python 3.4 で導入され、いまや業界標準。
from pathlib import Path
p = Path("data/sales.csv")
print(p.exists()) # True / False(存在するか)
print(p.suffix) # .csv(拡張子)
print(p.stem) # sales(拡張子なしのファイル名)
print(p.parent) # data(親ディレクトリ)
# フォルダ内のファイル一覧
for file in Path(".").glob("*.csv"):
print(file)
文字列でパスを連結する os.path.join("data", "sales.csv") より、Path("data") / "sales.csv" のほうが読みやすい、というのがモダンな Python の流儀です。
💡 ポイント 標準ライブラリの代表選手:
math(数学関数)、random(乱数)、datetime(日付)、os(OS との連携)、pathlib(モダンなパス操作)。これらだけで業務スクリプトの大半が書けます。
講師の現場メモ:「『コピペすればよい』と思っていた新人が、関数を書けるようになるまで」
私(平野)が、独立後に支援した中堅商社の事務職向け Python 研修での経験です。受講生は 20 代後半の事務職の方で、「Excel は得意だが、プログラミングは未経験」というよくある背景でした。
最初の 3 か月、彼女は順調に進みました。Hello World、変数、if、for、リスト——すべて手応えがありました。「Python は思ったより楽しい」と笑顔でした。ただ、関数の章に入ったとき、急に手が止まりました。「関数を書く意味がわからない」「コピペで動くなら、それでよいのでは」と。
私は、彼女が書いていたスクリプトを見せてもらいました。社内の受発注データを処理するスクリプトで、長さは 200 行。同じような処理が、3 か所に丸ごとコピーされていました。各場所で少しずつ違う変数名で書かれていて、修正が入るたびに 3 か所すべてを書き換えていました。1 か所だけ書き直し忘れて、出力結果がおかしくなったこともあったそうです。
私は彼女に提案しました。「3 か所のコピーを、1 つの関数にしてみませんか」。彼女は「やってみます」と渋々ながら取り組みました。30 分後、彼女はスクリプトを 200 行から 80 行に減らしていました。コピーが集約され、関数に名前が付き、引数で違いが表現されていました。
そのとき彼女はぽつりと言いました。「最初は関数を作る手間が面倒だと思っていました。けれど、書いてみたら、もとの 200 行よりむしろ書く時間が短かったです。なぜでしょう」。
私は答えました。「関数を作るときは『この処理は何をしているか』を 1 文で言語化する作業が要ります。その言語化が、頭の中の整理を加速するんです。だから、書く前に時間がかかるように見えて、トータルでは速くなる。何より、半年後にコードを見直したときの理解の速さが、大幅に違いますよ」。
その後、彼女は関数を積極的に書くようになりました。社内の Python 利用者会で、自分の経験を「コピペ脱出物語」として共有し、ほかの方々の参考になっていました。
このときに私が感じたのは、関数の本質は「コードを減らすこと」ではなく「処理を言語化すること」だ、ということです。total_sales、average_sales、report——名前を付ける作業を通じて、業務ロジックそのものが整理されます。AI 駆動開発が当たり前になった 2026 年でも、「処理に名前を付ける」スキルは、コードを書く本人にとって最大の学びだと考えます。本コースで関数を扱うのは、皆さんに「言語化の道具」を持ち帰ってほしいからです。
まとめ
このレッスンでは、以下のことを学びました。
- 関数は「操作に名前を付け、何度でも呼び出せる」道具。再利用・読みやすさ・保守性の 3 つの利点を持つ
def 関数名(引数):で定義、returnで値を返す。複数の値を返すときはタプルでまとめてアンパック- デフォルト引数(指定しなかったときの値)とキーワード引数(引数名を指定して渡す)を使いこなす
- スコープ:関数内のローカル変数は外から見えない、グローバル変数は中から読めるが書き換えには
globalが必要。引数と戻り値でやり取りするスタイルが推奨 - 「1 つの関数は 1 つの仕事」を意識して、業務ロジックを複数の関数に分割する
- モジュールは
importで読み込み、from … import …・import … as …の使い分けも覚える - 標準ライブラリの代表選手:
math・random・datetime・os・pathlib
次のレッスンでは、ファイル入出力と例外処理を扱います。Python から CSV や JSON を読み書きし、エラーをきれいに処理する方法を学びます。
確認クイズ
このレッスンの理解度をチェックしましょう。