troubleshooting2024-10-20·7 min·259/348

Python sys.path 설정과 모듈 임포트 문제 해결

Python의 sys.path를 이해하고 모듈 임포트 에러를 해결하는 방법을 알아봅니다.

Python sys.path 설정과 모듈 임포트 문제 해결

Python에서 모듈을 임포트할 때 발생하는 ModuleNotFoundErrorImportError는 sys.path 설정과 밀접한 관련이 있습니다.

Environment

$ python --version
Python 3.11.5

$ echo $PYTHONPATH
/home/user/projects/lib

$ pwd
/home/user/projects/myapp

Problem: ImportError 발생

$ python main.py
Traceback (most recent call last):
  File "main.py", line 1, in 
    from utils.helpers import format_date
ModuleNotFoundError: No module named 'utils'

프로젝트 구조:

myapp/
├── main.py
├── utils/
│   ├── __init__.py
│   └── helpers.py
└── models/
    ├── __init__.py
    └── user.py

Analysis: sys.path 확인

# check_path.py
import sys
import os

print("Python Path:")
for i, path in enumerate(sys.path):
    print(f"  {i}: {path}")

print("\nCurrent Directory:", os.getcwd())
print("Script Location:", os.path.dirname(os.path.abspath(__file__)))

출력:

Python Path:
  0: 
  1: /usr/lib/python311.zip
  2: /usr/lib/python3.11
  3: /usr/lib/python3.11/lib-dynload
  4: /home/user/.local/lib/python3.11/site-packages

Current Directory: /home/user/projects/myapp
Script Location: /home/user/projects/myapp

현재 디렉토리가 sys.path에 포함되어 있지 않습니다.

Solution: sys.path 수정 방법

방법 1: 현재 디렉토리 추가

# main.py
import sys
import os

# Add current directory to path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))

# Now import works
from utils.helpers import format_date
from models.user import User

print(format_date("2024-01-15"))

방법 2: PYTHONPATH 환경 변수

# Linux/Mac
export PYTHONPATH="${PYTHONPATH}:/home/user/projects/myapp"
python main.py

# Windows PowerShell
$env:PYTHONPATH = "$env:PYTHONPATH;C:\Users\user\projects\myapp"
python main.py

# Windows CMD
set PYTHONPATH=%PYTHONPATH%;C:\Users\user\projects\myapp
python main.py

방법 3: .pth 파일 사용

# Create .pth file in site-packages
echo "/home/user/projects/myapp" > /usr/lib/python3.11/site-packages/myapp.pth

# Or in virtual environment
echo "/home/user/projects/myapp" > venv/lib/python3.11/site-packages/myapp.pth

방법 4: pip install -e (개발 모드)

# Create setup.py or pyproject.toml first
$ pip install -e .

# Project is installed in editable mode
# Changes to source code are immediately reflected
# pyproject.toml
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.backends._legacy:_Backend"

[project]
name = "myapp"
version = "0.1.0"
dependencies = []

[tool.setuptools.packages.find]
where = ["."]

Advanced: 패키지 구조 최적화

Relative Import 활용

# models/user.py
from . import db  # Relative import from same package

# Or
from ..utils.helpers import format_date  # Import from parent package

init.py로 인터페이스 제공

# utils/__init__.py
from .helpers import format_date, parse_date
from .validators import validate_email

__all__ = ['format_date', 'parse_date', 'validate_email']

프로젝트 구조 예시

project/
├── pyproject.toml
├── src/
│   └── mypackage/
│       ├── __init__.py
│       ├── core/
│       │   ├── __init__.py
│       │   └── engine.py
│       └── utils/
│           ├── __init__.py
│           └── helpers.py
└── tests/
    ├── __init__.py
    └── test_core.py
# src/mypackage/__init__.py
__version__ = "0.1.0"

from .core.engine import Engine
from .utils.helpers import format_date

Troubleshooting Checklist

# 1. sys.path 확인
$ python -c "import sys; print('\n'.join(sys.path))"

# 2. 모듈 검색 경로 확인
$ python -c "import sys; help(sys.path)"

# 3. 현재 디렉토리 확인
$ python -c "import os; print(os.getcwd())"

# 4. 환경 변수 확인
$ echo $PYTHONPATH

# 5. 패키지 설치 확인
$ pip list | grep mypackage

# 6. ImportError 상세 확인
$ python -v -c "import mypackage" 2>&1 | grep mypackage

Lessons Learned

  1. sys.path 이해: Python은 sys.path에 나열된 디렉토리를 순서대로 검색하여 모듈을 찾습니다.

  2. PYTHONPATH 활용: 프로젝트 루트를 PYTHONPATH에 추가하면 모든 모듈을 임포트할 수 있습니다.

  3. pip install -e: 개발 중에는 패키지를 개발 모드로 설치하면 소스 변경이 즉시 반영됩니다.

  4. Relative Import: 패키지 내부에서는 상대 경로 임포트를 사용하면 더 깔끔한 코드를 작성할 수 있습니다.

  5. IDE 설정: VSCode, PyCharm 등은 각각의 sys.path 설정 방법이 있으므로 IDE 설정도 확인하세요.


This blog does not accept any external sponsorships, affiliate marketing, or ad revenue.