📑

Pythonで自作パッケージ・モジュールをimportする際に気を付けるべきこと

に公開

「ModuleNotFoundError」になったり、何故かならなかったり、挙動が不安定だった過去を反省し、Pythonで自作パッケージ・モジュールをimportする際に気を付けることを整理してみた。

1. __init__.pyを入れること

ディレクトリをPythonにパッケージとして認識させるには__init__.pyが必要である。
これがないと単なるフォルダ扱いとなり、import に失敗する可能性が高い。

project/
 └── app/
      ├── __init__.py
      ├── main.py
      └── utils.py

main.py からは次のように呼び出せる。

from app import utils

Python 3.3以降は namespace package により__init__.pyなしでも動く場合があるが、ツールや実行環境で不安定になるため、実務では必ず置くべきである。

2. 相対インポートと絶対インポートを区別すること

相対インポート

現在のパッケージを基準に辿る方法である。

project/
 └── app/
      ├── __init__.py
      ├── main.py
      └── routers
          ├── users.py
          └── items.py
from . import utils
from .routers import users

上記インポート文で「.」が無いと、プロジェクト直下(project/)にrouters/があると解釈されてしまう。「.」をつけることで、今のこのファイルがあるパッケージ(今回でいうとapp)から探してねという意味になる

小規模では便利だが、ネストが深くなると可読性が落ちる。

絶対インポート

プロジェクトルートからのフルパスで指定する方法である。

from app import utils
from app.routers import users

可読性・保守性が高く、チーム開発では一般的である。ただしプロジェクトルートを PYTHONPATH に通すなど環境設定が必要になる。

3. まとめ

  • __init__.pyを必ず置き、パッケージとして認識させること。
  • 相対インポートは小規模向き、絶対インポートは実務向きである。
  • import エラーの多くは__init__.pyの不足か、インポート方法の誤りに起因する。

Discussion