モジュールとパッケージ

コードが大きくなるにつれて、すべてを 1 つのファイルに入れるのは賢明ではありません。モジュールを使うとコードを複数のファイルに分割でき、パッケージを使うと関連するモジュールを一緒に整理できます。モジュラープログラミングを学ぶことは、真の「エンジニアリング」への入り口です。


1. モジュールとは

Python では、.py ファイルがモジュールです。import を使って他のモジュールの機能を取り込めます:

例:標準ライブラリモジュールのインポート

PYTHON
# モジュール全体をインポート
import math
print(math.pi)              # 3.141592653589793
print(math.sqrt(16))        # 4.0

# 特定の関数をインポート
from random import randint
print(randint(1, 10))       # 1 から 10 の間のランダムな整数

# 複数のアイテムをインポート
from datetime import datetime, timedelta
now = datetime.now()
print(now)                  # 現在時刻
▶ 試してみよう

Python には標準ライブラリモジュールの大規模なコレクションが付属しています——mathrandomdatetimeosjson……これらは Python をインストールした時点で既に存在し、import するだけで使えます。

💡 標準ライブラリは Python の最大の利点の 1 つです:「Batteries Included」が Python の哲学です——日常的な機能のほとんどは標準ライブラリで提供されており、追加インストールは不要です。


2. カスタムモジュール

モジュールの作成は簡単です——.py ファイルを書くだけです。

my_tools.py

PYTHON
# これはカスタムモジュール:my_tools.py

def greet(name):
    return f"Hello, {name}"

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

PI = 3.14159

main.py(モジュールを使用)

例:カスタムモジュールのインポートと使用

PYTHON
# カスタムモジュールをインポート
import my_tools

print(my_tools.greet("Zhang San"))   # Hello, Zhang San
print(my_tools.add(5, 3))            # 8
print(my_tools.PI)                   # 3.14159
▶ 試してみよう
⚠️ 補足: カスタムモジュールファイルは、呼び出し元のファイルと同じディレクトリか、Python の検索パスに置く必要があります。最も一般的な初心者の間違いは、自分のモジュールをインポートするときに「ModuleNotFoundError」が出ることです——ファイルパスを確認してください。


3. if __name__ == "__main__"

これは非常に重要な Python のパターンです——ファイルをインポート可能なモジュールとしても、直接実行可能なスクリプトとしても機能させます:

例:if name の二重目的パターン

PYTHON
# calculator.py
def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

# 以下のコードは、このファイルが直接実行された場合のみ実行
if __name__ == "__main__":
    print("Testing calculator functions:")
    print(f"3 + 5 = {add(3, 5)}")
    print(f"10 - 4 = {subtract(10, 4)}")
▶ 試してみよう

この場合:

💡 すべての Python ファイルは __name__ 変数を持っています。 直接実行された場合は "__main__"、インポートされた場合はモジュール名になります。この機能により、同じファイルが「ライブラリ」と「スクリプト」の二重の目的を果たせます。


4. パッケージ

多数のモジュールがある場合は、パッケージを使って整理します——パッケージは __init__.py ファイルを含むディレクトリです:

TEXT
my_package/
├── __init__.py      ← このファイルが必要(空でも可)
├── math_tools.py
└── string_tools.py
PYTHON
# math_tools.py
def multiply(a, b):
    return a * b

def divide(a, b):
    if b == 0:
        return "Cannot divide by zero"
    return a / b
PYTHON
# string_tools.py
def reverse(text):
    return text[::-1]

def count_vowels(text):
    vowels = "aeiouAEIOU"
    return sum(1 for c in text if c in vowels)

例:パッケージからのモジュール使用

PYTHON
# パッケージを使用
from my_package import math_tools, string_tools

print(math_tools.multiply(3, 5))           # 15
print(string_tools.reverse("Python"))      # nohtyP
▶ 試してみよう

5. サードパーティライブラリと pip

Python の力は、豊富なサードパーティライブラリのエコシステムから来ています。pip でインストールします:

BASH
pip install requests          # HTTP リクエストライブラリ
pip install numpy             # 数値計算
pip install pandas            # データ分析
pip install flask             # Web フレームワーク

requirements.txt

プロジェクトを他の人と共有するときは、どのサードパーティライブラリが必要かを伝える必要があります。requirements.txt がその目的です:

TXT
requests==2.31.0
numpy==1.24.0
pandas==2.0.0
flask==3.0.0

受け取った側は 1 つのコマンドですべての依存関係をインストールできます:

BASH
pip install -r requirements.txt

requirements.txt の生成

BASH
pip freeze > requirements.txt
💡 プロジェクトの慣習: サードパーティライブラリを使用するプロジェクトは、ルートディレクトリに requirements.txt を置くべきです。これは基本的な Python プロジェクトの慣習です。ライブラリのバージョンが更新されても、pip install -r requirements.txt はあなたが使用した正確なバージョンをインストールし、互換性を保証します。


よくあるユースケース


❓ よくある質問

Q import mathfrom math import pi の違いは何ですか?
A import math はモジュール全体をインポートし、使用時は math.pi と書く必要があります。from math import pipi だけをインポートし、直接 pi と使えます。前者はより明確(pi の出所がわかる)、後者はより簡潔です。普遍的な標準はありませんが、ファイル内での一貫性は推奨されます。
Q __init__.py は空でなければなりませんか?
A いいえ、空でなくても構いません。__init__.py はパッケージがインポートされたときに実行されます。初期化コードを入れられます——__all__ を定義して from package import * の動作を制御したり、ユーティリティ関数を直接書いたりできます。ほとんどのシンプルなプロジェクトでは、__init__.py は確かに空です。
Q pip install はインストールしたライブラリをどこに置きますか?
A デフォルトでは、Python インストール先の Lib/site-packages/ ディレクトリに配置されます。異なる依存関係要件を持つプロジェクトがある場合は、仮想環境(venv)を使用してください——各プロジェクトが独自の依存関係ディレクトリを持ち、分離された状態を保ちます。python -m venv myenv で作成し、source myenv/bin/activate で有効化します。

📖 まとめ


📝 練習問題

  1. 初級(難易度 ⭐):モジュール geometry.py を作成し、2 つの関数 circle_area(radius)rectangle_area(width, height) を含めてください。その後、別のファイルでインポートして使用します。

  2. 中級(難易度 ⭐⭐)geometry.pyif __name__ == "__main__" ブロックを追加し、関数をテストしてください。直接実行するとテストが実行され、インポートするとスキップされることを確認します。

  3. 上級(難易度 ⭐⭐⭐):パッケージ string_utils/ を作成し、2 つのモジュール validators.py(検証関数:is_email()is_phone())と transformers.py(変換関数:to_snake_case()to_camel_case())を含めます。パッケージの外にテストスクリプトを作成し、これらの機能をインポートして使用します。

100%