なぜ -m を使うのか?
パスを覚えなくていい
# ❌ フルパスを毎回入力
$ python3 /Users/name/projects/myproject/scripts/analyzer.py
# ✅ モジュール名だけ
$ python3 -m analyzer
標準ツールの統一的な実行
$ python3 -m pip install numpy
$ python3 -m venv myenv
$ python3 -m http.server 8000
$ python3 -m json.tool data.json
パッケージとして正しく実行
# __init__.pyや__main__.pyが適切に処理される
$ python3 -m mypackage
よくある問題
myproject/
├── main.py
└── helper.py
# main.py
from helper import some_function
# ✅ 動く
$ cd myproject
$ python3 main.py
# ❌ エラー
$ python3 -m main
ModuleNotFoundError: No module named 'helper'
なぜエラーになる?
通常実行: スクリプトのディレクトリが検索パスに入る
-m実行: 現在のディレクトリが検索パスに入る
解決法:PYTHONPATH
即座に解決
$ PYTHONPATH=./myproject:$PYTHONPATH python3 -m main
永続的に設定
# ~/.bashrc or ~/.zshrc
export PYTHONPATH="$HOME/myproject:$PYTHONPATH"
実用例
1. 自作CLIツール
# エイリアスの代わりに
$ PYTHONPATH=~/tools:$PYTHONPATH python3 -m mytool --help
2. プロジェクト内のスクリプト
# どこからでも実行
$ PYTHONPATH=/path/to/project/src:$PYTHONPATH python3 -m analyzer
3. テスト実行
$ PYTHONPATH=.:$PYTHONPATH python3 -m pytest tests/
ベストプラクティス
プロジェクトごとに設定
# .envファイル
PYTHONPATH=./src:$PYTHONPATH
パッケージ化
# setup.py
from setuptools import setup
setup(name='mypackage', packages=['mypackage'])
$ pip install -e .
$ python3 -m mypackage # どこからでもOK
デバッグ
# 検索パスを確認
import sys
print(sys.path)
まとめ
-m を使う理由:
- パス指定不要
- 統一的なインターフェース
- パッケージとして正しく実行
エラーが出たら:
$ PYTHONPATH=必要なパス:$PYTHONPATH python3 -m module