「なんでこんな単純なコードが動かないんだ……」
そう思いながらデバッグに何時間も費やした経験、ありませんか?😅
実は最近、Pythonの「たった1文字の差」で3時間以上ハマるという事件が話題になっています。
原因は .(ドット)1つ。相対インポートの罠です。
「え、そんなことで?」と思ったあなた、これが意外と深い話なんですよね。
🔍 何が起きたのか?「.」1文字の恐怖

問題が起きやすいのは、こういう場面です。
# ❌ これが動かない(スクリプトとして直接実行したとき)
from .utils import helper
# ✅ こちらは動く(絶対インポート)
from utils import helper
ポイントをまとめるとこんな感じです👇
from .utils import helperは「相対インポート」=パッケージ内での相対的な参照- スクリプトを直接
python main.pyで実行すると、パッケージ構造が認識されず即エラー - エラーメッセージは
ImportError: attempted relative import with no known parent package
ドットがあると動かない、ないと動く。この差がわからないと本当に詰みます😇
🧩 なぜこうなるの?超かんたんに解説
イメージとしては、こんな感じです。
相対インポートは「自分がどのパッケージに属しているか」を前提にした書き方です。
でも python main.py で直接実行すると、Pythonは「このファイルはどこのパッケージにも属していない単独スクリプトだ」と判断します。
つまり、「所属不明なのに相対参照するな」とPythonに怒られているわけです。
# ✅ パッケージとして実行するなら -m オプションを使う
# ディレクトリ構成:
# myapp/
# __init__.py
# main.py ← from .utils import helper と書いている
# utils.py
# 正しい実行方法(myapp の親ディレクトリから)
# python -m myapp.main
ここが重要です🔑
python main.py→ 相対インポートは使えないpython -m myapp.main→ パッケージとして認識され、相対インポートが使える- プロジェクトに
__init__.pyがあるかどうかも必ず確認しておきましょう
😤 それでもPythonを選ぶ理由

正直、こういう罠はPythonのあちこちにあります。
インデント地獄、サイレントなXMLエラー、そして今回の相対インポート……。
「開発者は頭がおかしいのか?」と叫びたくなる気持ち、めちゃくちゃわかります🤣
でも、それでもAI開発・データ処理・自動化においてPythonの生産性は圧倒的です。
ローカルLLMの制御、バッチ処理、ライブラリの豊富さ。これを捨てるのはもったいない。
罠を知っていれば、怖くない。それだけです💪
📝 まとめ
- 相対インポート(
.utils)はパッケージ実行時のみ有効 - 直接実行するなら絶対インポートか
python -mを使う - 「なぜか動かない」の多くは、実行方法とインポート方式のミスマッチ
「たった1文字」で詰まった経験、あなたにもきっとあるはず。
この記事が同じ沼にはまった誰かの助けになれば嬉しいです😊
ぜひ実際のプロジェクトで試してみてください!


