本文へスキップ
スキルアップカレッジ

関数とモジュール——コードに名前を付け、組み合わせる

レッスン5:関数とモジュール——コードに名前を付け、組み合わせる

このレッスンで学ぶこと

  • 関数の発想(操作に名前を付け、繰り返し使う)を理解する
  • def での関数定義、引数戻り値の書き方を身につける
  • デフォルト引数とキーワード引数を理解する
  • ローカル変数とグローバル変数のスコープの違いを把握する
  • 複数の関数を組み合わせて 1 つの業務を表現する
  • import でモジュールを読み込み、標準ライブラリの代表選手(mathrandomdatetimeospathlib)を活用する

前回のレッスンで、リストタプル辞書集合の 4 つのデータ構造を扱いました。データを表現する手段がそろってきたところで、次の課題は「処理に名前を付ける」「処理を組み合わせる」ことです。本レッスンでは、関数とモジュールという、コードを構造化する 2 つの基本道具を扱います。

関数の発想

関数は「操作に名前を付けて、何度でも呼び出せるようにする」道具です。Excel の関数(SUM、IF、VLOOKUP など)の発想に近く、入力(引数)を渡すと結果(戻り値)が返ってきます。

関数を使う 3 つの利点

  • 再利用:同じ処理を何度も使い回せる
  • 読みやすさ:処理に名前が付くので、コードが文章のように読める
  • 保守性:修正箇所が 1 つに集約され、変更が楽

Python の組み込み関数(復習)

これまでに、すでにいくつかの組み込み関数を使ってきました。

print("Hello")      # 表示
len("Python")       # 文字数を数える
sum([1, 2, 3])      # 合計
type(5)             # 型を調べる
int("30")           # 型変換

これらは Python に最初から組み込まれている関数です。本レッスンでは、これらに加えて、自分で関数を定義する方法を学びます。

💡 ポイント 関数は「操作に名前を付け、何度でも呼び出せる」道具で、再利用・読みやすさ・保守性の 3 つの利点があります。printlensumtypeint などはすでに使ってきた組み込み関数です。

関数の定義——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_salesaverage_salesreport)に分けたことで、それぞれの役割が明確になり、テストや修正もしやすくなりました。

「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 mathmath モジュールを読み込み、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    # 業界の慣習

pandaspd、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_salesaverage_salesreport——名前を付ける作業を通じて、業務ロジックそのものが整理されます。AI 駆動開発が当たり前になった 2026 年でも、「処理に名前を付ける」スキルは、コードを書く本人にとって最大の学びだと考えます。本コースで関数を扱うのは、皆さんに「言語化の道具」を持ち帰ってほしいからです。

まとめ

このレッスンでは、以下のことを学びました。

  • 関数は「操作に名前を付け、何度でも呼び出せる」道具。再利用・読みやすさ・保守性の 3 つの利点を持つ
  • def 関数名(引数): で定義、return で値を返す。複数の値を返すときはタプルでまとめてアンパック
  • デフォルト引数(指定しなかったときの値)とキーワード引数(引数名を指定して渡す)を使いこなす
  • スコープ:関数内のローカル変数は外から見えない、グローバル変数は中から読めるが書き換えには global が必要。引数と戻り値でやり取りするスタイルが推奨
  • 「1 つの関数は 1 つの仕事」を意識して、業務ロジックを複数の関数に分割する
  • モジュールは import で読み込み、from … import …import … as … の使い分けも覚える
  • 標準ライブラリの代表選手:mathrandomdatetimeospathlib

次のレッスンでは、ファイル入出力と例外処理を扱います。Python から CSV や JSON を読み書きし、エラーをきれいに処理する方法を学びます。


確認クイズ

このレッスンの理解度をチェックしましょう。