Python Module
Python 모듈과 패키지 이해하기
모듈 Module
파이썬에서 모듈은 파이썬 코드가 들어 있는 하나의 .py 파일로,
함수, 클래스, 변수 등을 논리적으로 묶은 코드 단위입니다.
# math_utils.py
def add(a, b):
return a + b
def sub(a, b):
return a - b
# main.py
import math_utils
print(math_utils.add(3, 5)) # 8
모듈은 코드를 관리하기 쉬운 단위로 나누고 코드 재사용을 위해 사용됩니다.
예를 들어, math_utils.py라는 파일은 수학 함수를 포함하는 모듈이 될 수 있습니다.
파이썬 패키지 Package
패키지는 여러 모듈을 디렉토리 구조로 묶은 것입니다.
__init__.py가 속한 폴더는 패키지로 인식됩니다.
파이썬 패키지는 파이썬의 모듈 네임스페이스를 구조화하는 방법입니다.
__init__.py 파일을 포함하는 디렉터리가 하나의 패키지가 되며,
하나의 패키지는 여러 모듈이나 하위 패키지를 포함할 수 있습니다.
javascript ESM에서 index 파일의 역할과 비슷한 것으로 이해했습니다.
예시 패키지
utilities
├── __init__.py
├── math_utils.py
└── string_utils.py
utilities는 두 개의 모듈을 포함하는 패키지입니다.
- 추가 내용: 파이썬 3.3 이상에서는
__init__.py없이도 패키지로 인식할 수 있으나, 명시적으로init파일을 추가한느 것이 유지보수에 좋습니다.
임포트 Import
파이썬에서 모듈과 패키지를 임포트하는 일반적인 방법은 다음과 같습니다:
import math_utils
result = math_utils.add(5, 3)
# from <모듈명> import <함수명>
from math_utils import add
result = add(5, 3)
-
import module_name
모듈을 임포트하며, 모듈 이름을 접두사로 사용하여 내용에 접근해야 합니다. -
from module_name import function_name
모듈에서 특정 속성이나 함수를 현재 네임스페이스로 직접 임포트합니다. -
from module_name import *(비추천) 모듈의 모든 공개 이름을 임포트합니다 (네임스페이스 오염 때문에 큰 모듈에서는 권장하지 않습니다).
모듈 경로 Module Path
모듈을 임포트할 때 파이썬은 다음 순서로 모듈을 검색합니다:
- 입력 스크립트가 실행된 현재 디렉터리.
- 환경 변수
PYTHONPATH에 포함된 디렉터리 목록. - 설치에 따라 결정되는 기본 디렉터리들 (예: 표준 라이브러리 디렉터리).
파이썬이 검색하는 디렉터리 목록은 sys.path를 확인하여 볼 수 있습니다:
import sys
print(sys.path)
궁금해서 더 찾아봤는데, 파이썬에서도 import된 모듈, 패키지의 의존성을 정적분석한 후에 코드를 실행한다고 합니다.
모듈/패키지 조직 패턴
- **단일 책임 모듈:하나의 모듈은 한가지 책임을 갖도록 구성합니다.
- 하위 모듈이 있는 패키지: 큰 프로젝트에서는 관련 모듈을 패키지와 하위 패키지로 조직합니다.
- 네임스페이스 패키지: 매우 큰 프로젝트나 분산 패키지에서는 네임스페이스 패키지를 사용하여 단일 패키지를 여러 디렉터리에 나눌 수 있습니다.
1. 단일 책임
하나의 파일이 하나의 역할만 담당하도록 구성합니다.
# database.py
def connect():
pass
def close():
pass
2. 유틸리티 모듈
여러 경로에서 공통으로 쓰이는 기능을 모듈로 만들어 재사용합니다.
# utils/logger.py
import datetime
def log(message):
print(f"[{datetime.datetime.now()}] {message}")
# main.py
from utils.logger import log as Logger
# ... 코드 중략, try-exception 블록에서 예외처리 logger 프린트
exception as e:
Logger(e.message)
3. 계층적 패키지 구조
- 대규모 프로젝트에서 기능별로 패키지를 나눈 뒤 구조화합니다.
project/
├── core/
│ ├── __init__.py
│ ├── database.py
│ └── config.py
├── services/
│ ├── __init__.py
│ ├── user_service.py
│ └── payment_service.py
└── utils/
├── __init__.py
└── logger.py
4. 진입점 Entry point 스크립트
__main__.py를 통해 패키지를 실행 가능하도록 구성합니다
tree
my_app/
├── __init__.py
├── __main__.py
└── core/
└── run.py
python -m my_app
모듈 구성 Tip
추가로 알게된 파이썬 모듈 작성 시 따르면 지침을 공유합니다:
- 의미 있는 모듈 및 패키지 이름을 사용
- 모듈 이름은 소문자 + 밑줄(_) 로 구성
- 모듈은 단일 책임에 집중하도록 하세요.
- 순환 임포트를 방지해야 합니다.
- 패키지 초기화 + 노출 내용 제어를 위해
__init__.py파일을 사용합니다. - 모듈과 함수에 문서 문자열(docstring)을 작성하세요. (
"""") eslint룰처럼, 코드 포맷팅에는 일반적으로PEP 8이라는 파이썬 스타일 가이드라인를 따른다고 합니다.- 전역 실행 코드는
if __name__ == "__main__":분기문 블록에서 실행시킵니다. - 절대 경로
import사용을 권장한다고 합니다. (from my_app.utils import logger) - 외부 의존성은
requirements.txt파일에 명시하는 것이 좋다고 합니다.