[에러#4] ImportError: cannot import name … 오류 정리

한줄 요약:
모듈은 있는데 “그 이름을 못 가져오겠다”는 뜻.
👉 이름 노출, 순환 참조, 버전 불일치, 파일명 충돌을 점검하면 99% 해결!


1. 이 에러가 의미하는 것

  • from X import Y에서 X는 찾았지만 Y가 없음
  • 원인 4대장
    1. 이름 없음(해당 모듈에 그 심볼이 정의/노출되지 않음)
    2. 순환 참조(circular import)
    3. 버전·경로 불일치(설명과 설치본이 다름)
    4. 파일명 충돌/가짜 모듈(내 파일이 표준 모듈/패키지 이름과 겹침)

2. 대표 에러 예시

ImportError: cannot import name 'User' from 'models'
ImportError: cannot import name 'Flask' from 'flask'
ImportError: cannot import name 'load_workbook' from 'openpyxl'

3. 해결 로드맵(빠른 점검 순서)

  1. 그 이름이 실제로 있는지 확인 import X; print(dir(X))Y가 목록에 없다면 그 모듈엔 그 이름이 없음 (또는 다른 경로에 존재)
  2. 정식 가져오기 경로 문서 확인
    • 예: from openpyxl import load_workbook (✅)
    • from openpyxl.utils import load_workbook (❌, 경로 다름)
  3. 순환 참조 의심(서로가 서로를 import)
    • a.pyb.py import, b.py → 다시 a.py import
    • 해결: 공통 코드를 c.py로 분리하거나, 함수 안에서 지연 import
  4. 내 파일명이 충돌하는지 확인
    • 예: flask.py, requests.py, email.py, models.py
    • 해결: 파일명 변경 + __pycache__/ 삭제
  5. 패키지 버전/노출 정책 확인
    • 같은 라이브러리라도 버전에 따라 import 경로가 달라짐
    • 해결: pip show <pkg> 버전 확인 후 문서 기준 경로로 수정
    • 필요 시 업/다운그레이드 python -m pip install <pkg>==<버전>
  6. 상대/절대 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

  1. 실제 경로 보기
import X, inspect
print(X.__file__)
  1. 현재 sys.path 점검
import sys; print("\n".join(sys.path))
  1. 이름 존재 여부
import X; print("Y" in dir(X))
  1. 런타임 지연 import 시도
def use_feature():
    from pkg.module import Y
    Y()
  1. 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 빠른 세팅(확장, 단축키, 디버깅)

댓글 남기기

광고 차단 알림

광고 클릭 제한을 초과하여 광고가 차단되었습니다.

단시간에 반복적인 광고 클릭은 시스템에 의해 감지되며, IP가 수집되어 사이트 관리자가 확인 가능합니다.