プログラミングを進めていくと、コードは必然的に長くなり、一つのファイルで管理するのが難しくなってきます。機能ごとにファイルを分割し、再利用しやすく、メンテナンスしやすい構造にすることが、効率的な開発の鍵となります。この章では、Pythonでコードを整理するためのモジュールとパッケージという仕組み、そしてPythonの強力な武器である標準ライブラリの活用方法について学びます。
Pythonでは、1つの .py
ファイルが1つのモジュールとして扱われます。モジュールを使うことで、関連する関数やクラスを一つのファイルにまとめ、他のプログラムから再利用可能な「部品」として扱うことができます。これは、他の言語におけるライブラリやソースファイルのインポート機能に似ています。
モジュールを利用するには import
文を使います。Pythonには多くの便利なモジュールが標準で用意されています(これらを標準ライブラリと呼びます)。例えば、数学的な計算を行う math
モジュールを使ってみましょう。
出力:
3.141592653589793
4.0
毎回 math.
と書くのが面倒な場合は、いくつかの書き方があります。
from ... import ...
: モジュールから特定の関数や変数だけを取り込む
as
(別名): モジュールに別名をつけて利用する
注意 ⚠️:
from math import *
のようにアスタリスク (*
) を使うと、そのモジュールのすべての名前(関数、変数、クラス)が現在の名前空間にインポートされます。一見便利に見えますが、どの名前がどこから来たのか分からなくなり、意図しない名前の上書きを引き起こす可能性があるため、特別な理由がない限り避けるべきです。
自分でモジュールを作成するのも簡単です。関連する関数をまとめた .py
ファイルを作成するだけです。ここからは複数のファイルが必要になるため、再びスクリプトファイルで説明します。
utils.py
の作成:
まず、便利な関数をまとめた utils.py
というファイルを作成します。
python utils.py
if __name__ == "__main__":
の重要性 この記述はPythonの定型句です。
- スクリプトが直接実行された場合、そのスクリプトの
__name__
という特殊変数は"__main__"
になります。- スクリプトがモジュールとして
import
された場合、__name__
はファイル名(この場合は"utils"
)になります。 これにより、モジュールとしてインポートされた際には実行したくないテストコードやデモコードを記述することができます。他言語経験者にとっては、プログラムの「エントリーポイント」を定義するmain
関数のような役割と考えると分かりやすいでしょう。
main.py
からの利用:
次に、utils.py
と同じディレクトリに main.py
を作成し、utils
モジュールをインポートして使います。
python main.py
このように、機能ごとにファイルを分割することで、コードの見通しが良くなり、再利用も簡単になります。
プロジェクトがさらに大きくなると、多数のモジュールを管理する必要が出てきます。パッケージは、複数のモジュールをディレクトリ構造で階層的に管理するための仕組みです。
パッケージは、簡単に言うとモジュールが入ったディレクトリです。Pythonにそのディレクトリをパッケージとして認識させるために、__init__.py
という名前のファイルを置きます(近年のPythonでは必須ではありませんが、互換性や明示性のために置くのが一般的です)。
以下のようなディレクトリ構造を考えてみましょう。
my_project/
├── main.py
└── my_app/
├── __init__.py
├── models.py
└── services.py
my_app
がパッケージ名になります。__init__.py
は空でも構いません。このファイルが存在することで、my_app
ディレクトリは単なるフォルダではなく、Pythonのパッケージとして扱われます。models.py
と services.py
が、my_app
パッケージに含まれるモジュールです。main.py
からこれらのモジュールをインポートするには、パッケージ名.モジュール名
のように記述します。
# パッケージ内のモジュールをインポート
from my_app import services
# servicesモジュール内の関数を実行 (仮の関数)
# user_data = services.fetch_user_data(user_id=123)
# print(user_data)
__init__.py
には、パッケージがインポートされた際の初期化処理を記述することもできます。例えば、特定のモジュールから関数をパッケージのトップレベルにインポートしておくと、利用側でより短い記述でアクセスできるようになります。
# my_app/__init__.py
# servicesモジュールからfetch_user_data関数をインポート
from .services import fetch_user_data
print("my_app package has been initialized.")
このようにしておくと、main.py
から以下のように直接関数をインポートできます。
# main.py
# __init__.pyで設定したおかげで、短いパスでインポートできる
from my_app import fetch_user_data
user_data = fetch_user_data(user_id=123)
print(user_data)
Pythonの大きな魅力の一つは、その「バッテリー同梱 (Batteries Included)」という哲学です。これは、Pythonをインストールしただけで、追加のインストールなしにすぐに使える膨大で強力な標準ライブラリが付属していることを意味します。
どんなライブラリがあるかを知るには、公式ドキュメントが最も信頼できます。
また、REPLの help()
や dir()
を使うと、モジュールの内容を簡単に確認できます。
ここでは、日常的によく使われる標準ライブラリをいくつか紹介します。
os
: オペレーティングシステムと対話するための機能を提供します。ファイルやディレクトリの操作、環境変数の取得などができます。
sys
: Pythonインタプリタ自体を制御するための機能を提供します。コマンドライン引数の取得や、Pythonの検索パスの確認などができます。
datetime
: 日付や時刻を扱うための機能を提供します。
json
: Web APIなどで広く使われているデータ形式であるJSONを扱うための機能を提供します。
これらの他にも、正規表現を扱う re
、乱数を生成する random
、HTTPリクエストを送信する urllib.request
など、数え切れないほどの便利なモジュールが標準で提供されています。何かを実装したいと思ったら、まずは「Python 標準ライブラリ 〇〇」で検索してみると、車輪の再発明を防ぐことができます。
この章では、Pythonのコードが複雑になるにつれて重要性を増す、整理と再利用のテクニックを学びました。ここで学んだ概念は、小さなスクリプトから大規模なアプリケーションまで、あらゆるレベルのPythonプログラミングで役立ちます。
.py
ファイルは1つのモジュールです。関連する関数やクラスをモジュールにまとめることで、コードを論理的な単位に分割できます。他のファイルからは import
文を使ってその機能を再利用できます。datetime
(日時)、os
(OS機能)、json
(データ形式) など、すぐに使える便利なモジュールが豊富に揃っています。これらを活用することで、開発を大幅に効率化できます。四則演算を行うための自作モジュールを作成し、別のファイルから利用してみましょう。
calculator.py
というファイルを作成し、以下の4つの関数を定義してください。
add(a, b)
: aとbの和を返すsubtract(a, b)
: aとbの差を返すmultiply(a, b)
: aとbの積を返すdivide(a, b)
: aをbで割った商を返す。ただし、b
が 0
の場合は「ゼロで割ることはできません」という文字列を返すようにしてください。practice5_1.py
というファイルを作成し、作成した calculator
モジュールをインポートします。practice5_1.py
の中で、calculator
モジュールの各関数を少なくとも1回ずつ呼び出し、結果を print
関数で表示してください。python practice5_1.py
標準ライブラリの datetime
と json
を使って、簡単な日報データを作成するプログラムを書いてみましょう。
datetime
モジュールを使って、現在の日付を YYYY-MM-DD
形式の文字列として取得します。author
: あなたの名前 (文字列)date
: 手順2で取得した日付文字列tasks
: その日に行ったタスクのリスト (例: ["会議", "資料作成", "メール返信"]
)json
モジュールを使い、手順3で作成した辞書を人間が読みやすい形式 (インデント付き) のJSON文字列に変換します。print
関数で表示してください。ヒント: datetime.datetime.now()
で現在時刻を取得し、.strftime('%Y-%m-%d')
メソッドで日付をフォーマットできます。json.dumps()
の indent
引数を指定すると、出力がきれになります。
python practice5_2.py