한줄 요약:
모듈은 있는데 “그 이름을 못 가져오겠다”는 뜻.
👉 이름 노출, 순환 참조, 버전 불일치, 파일명 충돌을 점검하면 99% 해결!
1. 이 에러가 의미하는 것
from X import Y에서 X는 찾았지만 Y가 없음- 원인 4대장
- 이름 없음(해당 모듈에 그 심볼이 정의/노출되지 않음)
- 순환 참조(circular import)
- 버전·경로 불일치(설명과 설치본이 다름)
- 파일명 충돌/가짜 모듈(내 파일이 표준 모듈/패키지 이름과 겹침)
2. 대표 에러 예시
ImportError: cannot import name 'User' from 'models'
ImportError: cannot import name 'Flask' from 'flask'
ImportError: cannot import name 'load_workbook' from 'openpyxl'
3. 해결 로드맵(빠른 점검 순서)
- 그 이름이 실제로 있는지 확인
import X; print(dir(X))→Y가 목록에 없다면 그 모듈엔 그 이름이 없음 (또는 다른 경로에 존재) - 정식 가져오기 경로 문서 확인
- 예:
from openpyxl import load_workbook(✅) from openpyxl.utils import load_workbook(❌, 경로 다름)
- 예:
- 순환 참조 의심(서로가 서로를 import)
a.py→b.pyimport,b.py→ 다시a.pyimport- 해결: 공통 코드를 c.py로 분리하거나, 함수 안에서 지연 import
- 내 파일명이 충돌하는지 확인
- 예:
flask.py,requests.py,email.py,models.py등 - 해결: 파일명 변경 +
__pycache__/삭제
- 예:
- 패키지 버전/노출 정책 확인
- 같은 라이브러리라도 버전에 따라 import 경로가 달라짐
- 해결:
pip show <pkg>버전 확인 후 문서 기준 경로로 수정 - 필요 시 업/다운그레이드
python -m pip install <pkg>==<버전>
- 상대/절대 import 혼용 정리 (내 패키지 구조)
- 패키지 내부라면 명시적으로:
from .utils import helper # 상대 from mypkg.utils import helper # 절대
- 패키지 내부라면 명시적으로:
4. 원인별 상세 가이드 & 예제
1) 모듈에는 있는데 __init__.py에서 노출을 안 함
폴더 패키지에서 상위에서 바로 가져오려 할 때 발생.
mypkg/
├─ __init__.py
└─ tools.py # 여기 안에 foo가 있음
❌ 실패
from mypkg import foo
✅ 해결 1: 경로를 정확히
from mypkg.tools import foo
✅ 해결 2: 노출시키기(선택)
# mypkg/__init__.py
from .tools import foo
__all__ = ["foo"]
2) 순환 참조(circular import)
# a.py
from b import func_b
def func_a(): return "A"
# b.py
from a import func_a
def func_b(): return "B"
이러면 로딩 순서 중간에 아직 생성되지 않은 이름을 찾다 실패.
✅ 해결 1: 공통 부분 분리
# common.py
def func_a(): return "A"
def func_b(): return "B"
# a.py
from common import func_b # 필요시
# b.py
from common import func_a
✅ 해결 2: 지연 import
# b.py
def func_b():
from a import func_a # 함수 안에서 import
return "B" + func_a()
3) 버전/경로 불일치
문서대로 썼는데 해당 버전에서는 경로가 다를 수 있어요.
- 확인
python -m pip show <패키지> python -c "import <pkg>, inspect; import inspect; print(inspect.getsource(<pkg>))" - 해결
- 문서(해당 버전) 기준
from ... import ...경로로 수정 - 필요한 버전으로 설치:
python -m pip install <pkg>==<원하는버전>
- 문서(해당 버전) 기준
4) 파일명 충돌/가짜 모듈
내가 만든 파일이 라이브러리 이름과 같으면 그 파일이 먼저 import됨.
- 예:
requests.py를 만들어 놓고import requests→ 내 파일을 불러와 실패 - 해결: 파일명 변경(
my_requests.py등),__pycache__/삭제 후 재실행# 폴더에서 캐시 폴더 삭제 # Windows rmdir /s /q __pycache__ # macOS/Linux rm -rf __pycache__
5. 디버깅 꿀팁 5
- 실제 경로 보기
import X, inspect
print(X.__file__)
- 현재 sys.path 점검
import sys; print("\n".join(sys.path))
- 이름 존재 여부
import X; print("Y" in dir(X))
- 런타임 지연 import 시도
def use_feature():
from pkg.module import Y
Y()
- IDE 인터프리터 확인
VSCode: Python: Select Interpreter / PyCharm: Project Interpreter
6. 자주 하는 실수 표
| 실수 | 증상 | 해결 |
|---|---|---|
from pkg import Y 가능한 줄 착각 | ImportError | 실제 경로 from pkg.mod import Y로 수정 |
models.py/email.py 등 충돌 이름 | 같은 이름 파일 먼저 import | 파일명 변경 + __pycache__ 삭제 |
| 순환 참조 | 특정 줄에서 ImportError | 공통 코드를 분리하거나 지연 import |
| 버전 차이 | 예전 글대로 따라 했는데 실패 | pip show로 버전 확인 후 문서 기준 경로 적용 |
7. 최종 체크리스트
dir(모듈)로 그 이름이 실제 존재하는가from 경로 import 이름이 문서와 일치하는가- 순환 참조를 끊었는가(분리/지연 import)
- 파일명 충돌이 없는가(표준/외부 패키지명과 겹치지 않음)
- 버전을 문서/코드와 맞췄는가
8. 요약 한 줄
이 에러는 “경로/이름/순서” 문제다.
정확한 import 경로 + 순환 참조 제거 + 파일명 충돌 방지로 해결! ✅
이전 강좌 👈 [에러#3] ModuleNotFoundError 대처법
다음 강좌 👉 [도구/환경#1] VSCode 빠른 세팅(확장, 단축키, 디버깅)