
最終更新: 2026-04-28
Python 環境ズレ デバッグチェックリストと再発防止コマンド集
noteの自動投稿スクリプトが「完走しているのに公開されない」状態に陥ったことがある。エラーはゼロ。ログに[SUCCESS] Posted: 2026-04-27T08:01:03が並んでいる。でもnoteのダッシュボードを開くと、記事は「下書き」のままだった。
原因を探るのに40分かかった。
python3 -c "import sys; print(sys.executable)" の一行で答えは出た。
この記事でわかること:
– Pythonがどの環境で動いているか一発で確認する方法
– 環境ズレが起きる原因パターン4種
– launchd/cronで実行するスクリプト固有の落とし穴
– 再発防止のためのデバッグチェックリスト(コピペ可)
どのPythonが動いているか——環境別のパスと罠
| 環境 | パス例 | よくある罠 |
|---|---|---|
| システムPython | /usr/bin/python3 | macOS標準、パッケージ追加不可 Pythonのバージョン違いによるパッケージ互換性エラー |
| Homebrew Python | /opt/homebrew/bin/python3 | brew upgrade後にバージョンが上がる |
| pyenv | ~/.pyenv/shims/python3 | VERSION設定ミスで別バージョンが動く |
| venv | /path/to/.venv/bin/python3 | activate忘れ・別シェルで実行すると無効 |
| Conda | /opt/miniconda3/envs/xxx/bin/python | base環境で動いて気づかない |
問題は「動く」という一点にある。エラーが出ないから気づけない——古い環境・古いライブラリのまま処理が完走し、意図しない挙動だけが残る。
40分溶かした実体験——何が起きていたか
スクリプトはnoteへの自動投稿処理だ。Playwright + Chromiumで動かしていて、記事生成→下書き保存→公開ボタンクリックという流れを自動化している。
完走する。ログも正常終了。でもnoteのダッシュボードには「下書き」が1件増えているだけ。
ログを掘り始めた。公開ボタンのURL検出ロジックを疑った。直接遷移する実装に切り替えたはずなのに、座標クリックの古い処理フローが動いている形跡がある。「あれ、コードを修正したはずでは?」——ここで気づいた。
コードは修正済みだった。新しいvenvにも配置済みだった。でもlaunchdのplistは古いPythonパスを参照したままだった。
# スクリプト冒頭に仕込んだログで一発でわかった
[BOOT] python = /usr/local/bin/python3 ← 古いHomebrew Python 3.10
# 期待値:
[BOOT] python = /Users/ichinosetaito/projects/note-auto/.venv/bin/python3
修正を加えたのは新しいvenvのコード。動いていたのは古いパスのコード。それだけの話。 パス・環境変数・作業ディレクトリの全設定を見直す
「それだけ」に40分かかった。
環境ズレが起きる4つの原因パターン
パターン1: launchd/cron がシェル設定を読まない
.bashrcや.zshrcに書いたPATHも、pyenvのeval "$(pyenv init -)"も、launchdから実行されるスクリプトには効かない。launchdは自前の最小限環境で動くので、python3と書いても/usr/bin/python3(macOSシステムPython)が拾われることがある。
# ❌ launchd plist の危ない書き方
<key>ProgramArguments</key>
<array>
<string>python3</string>
<string>/Users/ichinosetaito/projects/note-auto/post_note.py</string>
</array>
# ✅ venv内バイナリを絶対パスで指定する
<key>ProgramArguments</key>
<array>
<string>/Users/ichinosetaito/projects/note-auto/.venv/bin/python3</string>
<string>/Users/ichinosetaito/projects/note-auto/post_note.py</string>
</array>
私はこれを知っていたのに、venvを作り直したときにplistの更新を忘れた。
パターン2: venv を activate したのに別シェルで実行した
ターミナルのタブAでsource .venv/bin/activate、タブBでpython3 post_note.pyを実行する。タブBにはactivateが伝播していない——のでシステムのpython3が動く。エラーが出ないから気づかない。私はマルチタブ作業中にこれを3回やった。
パターン3: Homebrew アップデート後にパスが変わる
brew upgradeを実行するとPythonのバージョンが上がることがある。pyenvのshimが古いバージョンを参照し続け、PATHの順番次第でどちらが動くかが変わる。
# アップデート後に確認する
python3 --version
# Python 3.12.3 ← 上がっていた
# pyenvとHomebrewのどちらが優先されているか
which python3
# /opt/homebrew/bin/python3 ← pyenvより前にHomebrewのPATHが来ている
# pyenvで固定しているバージョン
pyenv version
# 3.11.9 (set by /Users/ichinosetaito/.pyenv/version)
# → shebang行のpython3.11を期待していたが、Homebrewの3.12が動いていた
アップデート後にwhich python3を確認する習慣がなかった。
パターン4: どの pip でインストールしたか不明
pip install playwrightしたはずなのにModuleNotFoundErrorが出る——これは大体、which python3とwhich pip3が別々の環境を指しているときに起きる。
# 食い違っている状態の例
which python3
# /Users/ichinosetaito/projects/note-auto/.venv/bin/python3 ← venv
which pip3
# /opt/homebrew/bin/pip3 ← venvのpipではない
# 解決策: python3 -m pip で実行する
python3 -m pip install playwright
# これで「今使っているpython3」に確実にインストールされる
コピペで使えるデバッグチェックリスト
「なんかおかしい」と思ったらこれを上から流す。
# 1. どのpythonが動くか
which python3
python3 -c "import sys; print(sys.executable)"
# 2. バージョン確認
python3 --version
# 3. pipとpythonが同じ環境を指しているか
python3 -m pip --version
# pip 24.0 from /Users/ichinosetaito/projects/note-auto/.venv/lib/python3.11/site-packages/pip (python 3.11)
# ↑ このパスがpython3のパスと一致しているかチェック
# 4. 対象パッケージが今の環境に入っているか
python3 -m pip show playwright
python3 -m pip show requests
# 5. launchd plistの参照先(macのみ)
grep -A 3 "ProgramArguments" ~/Library/LaunchAgents/com.taito.note-auto.plist
スクリプトの冒頭に仕込んでおくと、ログファイルを見ればどの環境で動いたか一発でわかる:
import sys, os, platform
print(f"[BOOT] python = {sys.executable}", flush=True)
print(f"[BOOT] version = {platform.python_version()}", flush=True)
print(f"[BOOT] cwd = {os.getcwd()}", flush=True)
launchd経由のスクリプトには必ずこれを入れるようにした。ログの先頭行を見るだけで、plistが正しいパスを参照しているかどうかわかる。
launchd 固有の落とし穴——plist 更新忘れ
今回の事故の根本はここだった。venvを作り直したとき、plistを更新しなかった。
plistを変更したらリロードが必要だ。unload→loadを忘れると古いplistが有効なまま動き続ける:
# plist変更後は必ずこれ
launchctl unload ~/Library/LaunchAgents/com.taito.note-auto.plist
launchctl load ~/Library/LaunchAgents/com.taito.note-auto.plist
# ロードされているか確認
launchctl list | grep taito
「変更が反映されていないのに反映されたと思う」状態がいちばん厄介だ。エラーが出ない、ログが綺麗に流れる、だから動いていると思い込む。
よくある質問
venv を activate したのに効いていないのはなぜ?
source .venv/bin/activateはそのシェルセッション内にのみ有効だ。launchd・cron・別プロセスからの呼び出しには伝播しない。解決策はvenv内のPythonバイナリを絶対パスで指定すること——/path/to/.venv/bin/python3 script.pyで直接実行するか、スクリプトのshebang行に#!/path/to/.venv/bin/python3と書く。
pip install したのに ModuleNotFoundError が出る
python3 -m pip --versionとpython3のパスが一致しているか確認する。食い違っていれば別環境にインストールしている。python3 -m pip install パッケージ名で実行すれば、今のpython3に紐づくpipが使われるので確実。
pyenv と venv はどちらを使えばいいか?
用途が違う。pyenvは「Pythonのバージョン」を切り替えるもの、venvは「同じバージョン内でパッケージを分離」するものだ。私はpyenvでプロジェクトごとにバージョンを固定したうえで、プロジェクトごとにvenvを切る構成にしている。launchdから実行するスクリプトはvenv内のバイナリを絶対パスで指定する——これだけで大半のトラブルは防げる。
スクリプトを修正したのに古い挙動のまま
「どの環境のコードを実行しているか」と「どの環境に修正を加えたか」がズレている可能性がある。python3 -c "import sys; print(sys.executable)"でPythonのパスを確認し、そのパスのプロジェクトディレクトリに最新コードが入っているかを確認する。launchd plistが古いパスを参照していないかも見る。今回の私の事故はまさにこれだった。
Homebrew の Python と pyenv が混在して混乱している
pyenv doctorで警告を確認する。PATHの順番が問題のことが多い。.zshrcでexport PATH="$HOME/.pyenv/bin:$PATH"を先頭に置くとpyenvが優先される。ただしlaunchdは.zshrcを読まないので、plistには絶対パスを書くのが前提だ。
まとめ
「動いているのに結果がおかしい」ときはsys.executableとpython3 -m pip --versionを最初に疑う。それだけで8割は解決する。
launchd/cronは.zshrcを読まない。絶対パス指定が前提で、plist変更後は必ずunload→loadが必要だ。venvのパスを変えたらplistも同時に更新する——片方だけ変えると今回の事故が再現する。
スクリプト冒頭にsys.executableをログ出力しておくと、ログファイルで環境を即確認できる。python3 -m pip installを使う習慣にすれば、pipとpythonが食い違う問題は起きなくなる。
40分は取り戻せないけど、チェックリストは残った。✨
この記事を読んだあなたに:
– launchd で Python スクリプトを自動実行する設定方法 /launchd-python-autorun
– pyenv + venv の環境構築を30分で終わらせる手順 /pyenv-venv-setup
– Python 自動化スクリプトのエラーログを Discord に飛ばす実装 /python-discord-error-log