ファイル1つが1つのモジュールになる
Pythonのコードが1つのスクリプトに収まらない規模になってきたら、ファイルを分割したくなりますよね。Pythonのモジュールシステムはとてもシンプルで、.pyファイルはそれだけで自動的にモジュールとして扱われ、ファイル名でそのままimportできます。
たとえば、util.pyというファイルがあったとしましょう。
# util.py
def greet(name):
return f"Hello, {name}"
PI = 3.14159
同じディレクトリにある別のファイル、たとえば main.py からは、次のように呼び出せます。
# main.py
import util
print(util.greet("Ada"))
print(util.PI)
python3 main.py を実行すると、Python は util.py を見つけて一度だけ実行します。そして、トップレベルで定義されているもの(関数、変数、クラス)はすべて util モジュールの属性としてアクセスできるようになります。
import の3つの書き方
モジュール全体を import する。 中身にはモジュール名経由でアクセスします。
特定の名前だけをインポートする。 こうすると、その名前をそのまま使えるようになります:
エイリアス(別名)を付けてインポートする。 モジュール名が長いときや、名前が被ってしまうモジュールを扱うときに便利です:
import numpy as np
import pandas as pd
# Now use np.array(...), pd.DataFrame(...), etc.
4つ目の書き方として from math import * があり、これはモジュール内のすべてを現在の名前空間に取り込みます。ただし、REPLでちょっと試すとき以外は使わない方が無難です。どの名前がどこから来たのか追えなくなりますし、気づかないうちに名前の衝突が起こることもあります。
import が実行されるタイミング
Python は、あるプログラムの中でモジュールが最初に import されたときに、そのモジュールのトップレベルのコードを一度だけ実行します。2回目以降の import では、すでに読み込まれているモジュールがそのまま返されます。つまり、次のような場合:
# setup.py
print("setup module loading...")
VALUE = 42
# main.py
import setup
import setup # imported twice — but "loading" only prints once
print(setup.VALUE)
"setup module loading..." が出力されるのは一度きりです。これは結構重要なポイントで、ファイルを開いたり print したりといった副作用をモジュールのトップレベルに書くと、import された瞬間に実行されてしまいます。たいていの場合これは意図した挙動ではないので、そういう処理は関数の中に入れておきましょう。
Python 標準ライブラリ
Python には最初から豊富な標準ライブラリが付属しています。ここまでにもいくつか登場しましたね。中でも日常的によく使うのは次のあたりです。
math—sqrt、sin、log、それにpiやeなどの定数。random— 乱数の生成、ランダムな選択、シャッフル。datetime— 日付と時刻の操作。json— JSON の読み書き。os、os.path— ファイルシステムのパスや操作。pathlib— モダンなパス操作。os.pathより書きやすいことが多いです。re— 正規表現。collections—Counter、defaultdict、dequeなどの便利なコレクション型。itertools、functools— イテレータや関数を扱うためのヘルパー群。csv— CSV ファイルの読み書き。
標準ライブラリは Python と一緒にインストール済みなので、pip install は不要です。
サードパーティパッケージと pip
標準ライブラリに入っていない機能を使いたいときは、Python Package Index(PyPI)に公開されている何十万ものパッケージから選べます。インストールは pip install を使います:
pip install requests
pip install pandas
pip install --upgrade requests
pip uninstall requests
インストールさえ済めば、あとは他のモジュールと同じように import で呼び出せます。
import requests
response = requests.get("https://api.example.com/data")
print(response.status_code)
正気を保ちながらパッケージを管理するためのコツをいくつか紹介します。
仮想環境(virtual environment)を使う
何でもかんでもグローバルに pip install するのは、後々痛い目を見ます。プロジェクトごとに必要なバージョンは違いますし、特定の Python バージョンに依存するパッケージもあります。さらに、環境によってはグローバルインストールに管理者権限が必要になることも。そこで登場するのが 仮想環境(virtual environment) です。プロジェクトごとに独立した Python 環境を用意できる仕組みです。
python3 -m venv .venv
source .venv/bin/activate # macOS/Linux
.venv\Scripts\activate # Windows
pip install requests
venv が有効になっている間は、pip でインストールしたパッケージはシステムではなくプロジェクトフォルダ内に入ります。作業が終わったら deactivate で抜けましょう。
依存パッケージをロックする
インストール済みパッケージの一覧を保存しておけば、他の人(もちろん未来の自分も)が同じ環境を再現できます。
pip freeze > requirements.txt
その後、こちらも書きます:
pip install -r requirements.txt
Poetry や pipenv、uv といったツールを使えばもっと快適に管理できますが、学習目的なら昔ながらの pip + requirements.txt の組み合わせで十分です。
python 自作モジュールの作り方
複数のファイルで使い回したい関数が出てきたら、専用のモジュールに切り出しましょう。命名規則は次のとおりです。
- ファイル名は
lower_snake_case.py。 - モジュール直下の関数や変数も
lower_snake_case。 - クラス名は
PascalCase。
# shopping.py
PRICES = {"apple": 0.50, "bread": 2.00}
def total(items):
return sum(PRICES[item] for item in items)
# main.py
from shopping import total, PRICES
print(total(["apple", "bread"]))
print(PRICES)
同じフォルダにある 2 つのファイルがお互いを import し合うと、うっかり循環インポート(circular import)が発生してしまうことがあります。定番の解決策は、共通で使うコードを 3 つ目のファイルに切り出して、両方からそれを import するようにすることです。
パッケージ:モジュールをまとめるフォルダ
モジュールの数が増えてきたら、パッケージとしてまとめましょう。パッケージとは、__init__.py ファイルを含んだフォルダのことです。
myproject/
├── main.py
└── utils/
├── __init__.py
├── text.py
└── numbers.py
では、続けます。
from utils.text import slugify
from utils import numbers
print(slugify("Hello, World"))
print(numbers.mean([1, 2, 3]))
__init__.py は空でも大丈夫で、このファイルがあること自体が utils を「パッケージですよ」と示す目印になります。最近の Python では __init__.py なしの「名前空間パッケージ」もサポートされていますが、最初のうちは明示的に置いておくほうが分かりやすいでしょう。
import がうまくいかないときのチェックリスト
ModuleNotFoundError: No module named X. パッケージがそもそもインストールされていないか、pip installしたときとは別の Python インタープリタで実行している可能性が高いです。仮想環境(venv)を使っているなら、ちゃんと有効化されているか確認しましょう。ImportError: cannot import name Y from X. モジュール自体はあるけれど、指定した名前がその中に見つからないパターンです。タイポがないか、そしてモジュールの中身に実際に何が定義されているかを確認してみてください。- 循環インポート(Circular import). 2つのモジュールが互いに import し合っている状態です。共通で使うコードを3つ目のモジュールに切り出して解決しましょう。
次は: サードパーティパッケージのインストール
自作モジュールだけでもかなりのことができますが、実際のプロジェクトではたいてい PyPI のライブラリ——requests や pandas、テストフレームワークなど——も組み合わせて使います。次のページでは pip の使い方、パッケージをきれいにインストールする方法、そしてプロジェクトの依存関係を記録しておく方法を紹介します。
よくある質問
Pythonのモジュールって何ですか?
ざっくり言うと、.pyファイルはすべてモジュールです。Pythonでは作成した.pyファイルがそのままモジュールになり、.pyを外したファイル名でimportできます。また、math・json・datetimeのようにPythonに最初から付属している「標準ライブラリ」も、そのまま使える便利なモジュール群です。
import X と from X import Y はどう違いますか?
import Xはモジュール全体を読み込み、中身はX.somethingのようにアクセスします。一方from X import YはYだけを現在の名前空間に取り込むので、そのままYとして使えます。名前が衝突しにくいのは前者、コードが短く書けるのは後者、という使い分けですね。
Pythonのパッケージはどうやってインストールしますか?
ターミナルでpip install パッケージ名を実行するだけでOKです。pipはPython公式のパッケージ管理ツールで、最近のPythonには最初から付属しています。プロジェクトごとに環境を分けたい場合は、先に仮想環境(venv)を作っておくと、パッケージが他のプロジェクトと混ざらず安心です。