Pythonの学習が進んでくると、1つのスクリプトに関数がどんどん増えて、画面をスクロールするだけで迷子になる…そんな経験はありませんか? コードを整理するための最強の武器が、自作モジュールです✨
処理を役割ごとに別ファイルへ切り出し、必要なときだけimportして使う──このスタイルを身につけると、メイン処理がスッキリ読みやすくなり、機能追加もバグ修正もぐっとラクになります。チーム開発や将来のあなた自身のためにも、ぜひ今日マスターしましょう🚀
モジュールとは、ざっくり言えば1つのPythonファイル(.py)のこと。標準ライブラリのosやmathのように、自分で作った.pyファイルも立派なモジュールとして他のファイルから呼び出せます📦
「自作モジュール」と聞くと「
pip installできるパッケージを公開すること?」と思いがちですが、それはまた別の話。ここでは同じプロジェクト内で自作の.pyファイルを呼び出すシンプルなやり方を扱います。
標準ライブラリをimportするのと同じ感覚で、自分のファイルもimportできる──この事実を知るだけで、設計の自由度が一気に広がります。
まずは最小構成で動きを確認しましょう。同じフォルダに2つのファイルを用意します。
module2.py(呼び出される側)
def func2():
print("func2です")
module1.py(呼び出す側)
import module2
def main():
module2.func2()
if __name__ == "__main__":
main()
ターミナルでpython module1.pyと実行すると、「func2です」と表示されます🎉 ポイントは次の3つです。
import module2:拡張子.pyを除いたファイル名を指定module2.func2():「モジュール名.関数名」で呼び出すif __name__ == "__main__"::このファイルが直接実行されたときだけ動かしたい処理を囲むif __name__ == "__main__" が必要なのか「Pythonって上から順に実行されるんだから、わざわざこのif文いらなくない?」と思った方、鋭いです👏 でも、これがないと困る場面があります。
たとえばmodule2.pyの末尾に、テスト用としてfunc2()をそのまま呼ぶ行を書いたとしましょう。すると…
# module2.py
def func2():
print("func2です")
func2() # ← if文で囲わずに書いた
この状態でmodule1.pyを実行すると、importした瞬間にfunc2()まで勝手に動いてしまうのです。つまり、他のファイルから読み込まれただけで意図しない処理が走ってしまう⚡
これを防ぐのがif __name__ == "__main__":です。この囲みの中に書いた処理は、そのファイルが直接実行されたときだけ動き、importされたときには動きません。
python module2.pyで直接実行 → 中の処理が動く(単体テストや動作確認に便利)import module2された → if文の中は実行されないこれにより、「単体でも動くし、ライブラリとしても使える」両刀使いのモジュールが作れます🗡️
プロジェクトが大きくなると、機能ごとにフォルダで分けたくなりますよね。フォルダ階層をまたいだimportも、書き方さえ知っていれば簡単です。
こんなファイル構成を考えてみましょう👇
project/
├── module1.py
└── sub_folder1/
└── sub_module1.py
sub_module1.py
def sub_func1():
print("sub_func1です")
module1.py
from sub_folder1 import sub_module1
def main():
sub_module1.sub_func1()
if __name__ == "__main__":
main()
from フォルダ名 import モジュール名の構文を使うと、サブフォルダの中のモジュールを呼び出せます。「.でつなぐとフォルダの階層を表す」と覚えればOK🌳
💡 Python 3.3より前のバージョンでは、フォルダの中に
__init__.pyという空ファイルを置かないとimportできませんでした。最近のバージョンでは不要ですが、古い環境を使う場合は念のため用意しておきましょう。
フォルダがさらに入れ子になっても、ドットでつなげば呼び出せます。
from sub_folder1.sub_sub_folder import sub_sub_module
ポイントは「実行されるメインスクリプト(module1.py)からの相対パス」で考えること。一番上の階層に実行ファイルを置き、その下に部品となるモジュール群を整理していくのが定石です📐
慣れてきたら、こんな構成でプロジェクトを組むと拡張に強くなります。
utils/、models/、views/)if __name__ == "__main__":を入れて、単体テストできるようにしておく「修正するときに、どのファイルを開けばいいか一目で分かる」状態を保てれば合格点。最初は2〜3ファイルから始めて、徐々に分割の感覚を掴んでいきましょう🌱
動画と合わせて手元に1冊あると、「どこで分割するのが正解か」という設計感覚が一気に育ちます📖
importや関数の基本に不安が残る方には、対話形式でやさしく解説してくれるこの一冊がぴったり。モジュール化の前提となる関数・クラスの知識をスムーズに整理できます。
変数・関数・モジュール・パッケージまでを一冊で網羅。「__name__とは何者か」という疑問にも自然に答えてくれる、迷ったらまずこれの定番です。
モジュール、パッケージ、名前空間、相対import・絶対importの違いまで踏み込んで学べる一冊。「動くコード」から「設計されたコード」へ進化したい方に最適です📈
大きなコードベースを「壊れにくく」保つための原則と実装テクニックがびっしり。モジュール境界の設計、型ヒント、テストとの関係まで網羅されており、中級者の必読書です。
「モジュールをどう設計すれば後で困らないか」という観点が章立てで整理されており、毎日のコーディングがすぐにレベルアップします。中級から上級への橋渡しに最適です。
import モジュール名とfrom モジュール名 import 関数名はどう使い分ける?「モジュール名を残したいなら前者、関数だけサクッと使いたいなら後者」と覚えるとシンプルです。前者はmod.func()と書くのでどこから来た関数か明確、後者はfunc()と短く書ける反面、名前の衝突に注意が必要です。プロジェクトが大きくなるほど前者が安心感があります🛡️
__init__.pyって結局必要?Python 3.3以降は必須ではありません。ただし、フォルダを「パッケージ」として明示したいときや、古いバージョンに対応する必要があるときは、空のままでも置いておくと安全です。パッケージ全体の初期化処理を書く場所としても使えます。
2つのモジュールがお互いをimportし合うと、エラーや予期しない挙動の原因になります。対処法は主に3つ。「共通機能を第3のモジュールに切り出す」「importを関数の中に書く(遅延import)」「そもそも依存関係を見直す」です。設計の見直しが本質的な解決策になることが多いです🔄
絶対importはfrom project.utils import helperのようにプロジェクトルートからのフルパスで書く方法。相対importはfrom .utils import helperのように現在位置からの相対パスで書く方法です。チーム開発では絶対importの方が読み手にやさしいので推奨されます👍
各モジュールにif __name__ == "__main__":でちょい動作確認を書いておくのが手軽です。本格的にやるならpytestを導入し、tests/フォルダを切ってテストファイルを並べる構成が定番。テストがあると、モジュール分割の安心感が段違いに上がります✅
自作モジュールは、Pythonでコードを書く人なら避けて通れない通過点であると同時に、一気にプロっぽさが増す強力な武器です。今回紹介したimportの書き方とif __name__ == "__main__":のイディオムさえ押さえれば、もう怖いものはありません🛠️
まずは2ファイルに分けるところから。慣れてきたらサブフォルダを切り、機能ごとにファイルを整理してみてください。気づいたとき、あなたのプロジェクトは「読みやすく、直しやすく、育てやすい」コードベースに変わっているはずです🌟 今日から早速、長くなったスクリプトをひとつ分割してみましょう!