HOWTO · Python

Python 애플리케이션을 위한 프로젝트 구조

Python 애플리케이션을 구성하는 방법 알아보기

이 페이지의 내용

유지 관리하기 좋은 Python 프로젝트는 루트를 필요한 항목으로 간결하게 구성하고, 관련 코드를 패키지로 묶으며, 애플리케이션에 필요한 경우에만 보조 폴더를 추가합니다. 프로그램의 실행 방식에 맞춰 구조를 선택하세요. 모듈식으로 구성해도 작은 모놀리스 하나로 배포할 수 있습니다.

애플리케이션에 맞는 구조 선택하기

명확한 프로젝트 구조는 코드를 찾고 유지 관리하며 협업자와 공유하기 쉽게 해 줍니다. 그렇다고 프로그램을 마이크로서비스로 나눠야 하는 것은 아닙니다. 작은 애플리케이션은 배포 가능한 프로그램 하나로 유지하면서 관련 코드를 모듈과 패키지로 묶을 수 있습니다. 프로젝트에 유용한 경계를 만들어 주는 경우에 디렉터리를 추가하고, 규모가 큰 프로젝트를 흉내 내려고 빈 폴더를 만들지는 마세요.

적절한 구조는 애플리케이션의 실행 방식과 구성 요소에 따라 달라집니다. 명령줄 도구에는 애플리케이션 코드, 종속성 정보, 테스트만 필요할 수 있습니다. 웹 애플리케이션에는 템플릿과 정적 파일도 필요할 수 있습니다. SQLite를 사용하는 프로젝트는 로컬 데이터베이스 파일을 만들 수 있지만, 데이터베이스 서비스에 연결하는 프로젝트는 대개 소스 트리 바깥에 데이터를 둡니다.

프로젝트 루트에서 시작하기

프로젝트 루트는 애플리케이션을 개발하고 테스트하고 문서화하고 패키징하는 데 사용하는 파일을 담는 디렉터리입니다. 흔히 README.md에는 설정 및 사용 방법을, LICENSE에는 다른 사람이 코드를 사용하고 배포할 수 있는 조건을 적습니다. pyproject.toml이나 requirements.txt 같은 파일로 종속성을 선언할 수도 있습니다. 파일마다 목적이 다르므로 모든 프로젝트에 각종 패키징 형식이나 종속성 형식이 필요한 것은 아닙니다.

Python 애플리케이션에 공통으로 필요한 진입점 파일명은 없습니다. 명령줄 프로그램은 python -m package_name으로 실행할 수 있고, 프레임워크나 패키징 설정에서 다른 명령을 지정할 수도 있습니다. 모든 프로젝트에 run.py나 setup.py가 필요하다고 가정하지 말고, 애플리케이션에 맞는 실행 방법을 사용하세요.

프로젝트에서 설치한 패키지를 분리하려면 로컬에 가상 환경을 만드세요. 가상 환경은 버전 관리에 포함하지 말고, 협업자는 종속성 정보로 각자의 환경을 만들 수 있습니다. .gitignore 파일에는 보통 가상 환경과 캐시를 비롯한 생성 파일을 제외하는 항목을 적습니다. 루트는 간결하게 유지하고, 프로젝트에 필요한 문서나 패키징 설정만 추가하세요.

애플리케이션 코드를 패키지로 구성하기

Python 모듈을 역할에 따라 묶으세요. 예를 들어 블로그에서는 계정 관련 코드를 users에, 게시물 관련 코드를 posts에 둘 수 있습니다. 이는 프로세스 안에서 코드를 구성하는 일반적인 방법입니다. 두 패키지 모두 하나의 애플리케이션 일부로 실행할 수 있으며, 독립된 서비스처럼 서로 통신할 필요가 없습니다.

일반 패키지에는 흔히 __init__.py 파일이 포함됩니다. 이 파일은 비어 있어도 되고, 패키지 인터페이스의 일부로 특정 이름을 공개할 수도 있습니다. 한편 Python은 이 파일을 생략할 수 있는 네임스페이스 패키지도 지원합니다. 따라서 __init__.py가 언제나 필요하다고 여기지 말고 프로젝트에서 선택한 패키지 방식과 도구를 따르세요. 여러 부분에서 공유하는 코드는 모듈이나 패키지에 두고, 폴더마다 같은 동작을 중복 구현하지 마세요.

필요에 따라 테스트, 문서, 웹 리소스 추가하기

tests 디렉터리를 사용하면 자동화된 검사를 애플리케이션 코드와 분리할 수 있습니다. 작은 프로젝트에서도 테스트는 유용합니다. 코드가 바뀔 때 기대한 동작을 더 쉽게 확인할 수 있기 때문입니다. README만으로 충분한 설명을 제공하기 어려워지면 docs 디렉터리에 사용자나 기여자를 위한 자세한 안내를 둘 수 있습니다.

웹 프로젝트에는 애플리케이션이 렌더링하는 HTML을 위한 templates 디렉터리와 CSS, JavaScript, 이미지 같은 리소스를 위한 static 디렉터리가 있는 경우가 많습니다. 정확한 위치는 프레임워크와 설정에 따라 달라집니다. 웹 애플리케이션이 아닌 명령줄 프로그램에는 보통 이 폴더가 필요하지 않습니다.

데이터베이스 모델은 선택한 아키텍처에 맞는 곳에 두면 됩니다. 프로젝트에 따라 models.py 같은 전용 모듈을 사용하거나 여러 모델 그룹을 위한 패키지를 만들 수 있습니다. database.db 같은 파일은 SQLite처럼 로컬 파일 기반 데이터베이스를 실제로 사용하는 경우에만 적절합니다. 애플리케이션이 다른 곳에 데이터를 저장한다면 소스 구조에 데이터베이스 파일을 추가하지 마세요.

예: 소규모 블로그 애플리케이션

이 블로그는 계정 코드와 게시물 코드를 별도의 패키지에 두고, 웹 전용 리소스와 프로젝트 지원 파일은 루트에 둡니다. 아래 트리는 출발점입니다. 프레임워크 규칙에 따라 템플릿, 모델, 정적 파일의 위치가 달라질 수 있습니다. 데이터베이스 파일은 로컬 SQLite 설정을 위한 것이며, 로컬 가상 환경은 버전 관리 대상 프로젝트 구조에서 의도적으로 제외했습니다.

다음 예제를 실행합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

layout = [
    "blog/",
    "├── README.md",
    "├── LICENSE",
    "├── pyproject.toml",
    "├── blog/",
    "│   ├── __init__.py",
    "│   ├── users/",
    "│   └── posts/",
    "├── templates/",
    "├── static/",
    "├── tests/",
    "└── database.db  (local SQLite only)",
]
print("\n".join(layout))
blog/
├── README.md
├── LICENSE
├── pyproject.toml
├── blog/
│   ├── __init__.py
│   ├── users/
│   └── posts/
├── templates/
├── static/
├── tests/
└── database.db  (local SQLite only)

트리에는 배포 설정과 프레임워크 세부 사항이 포함되어 있지 않으므로 사용하는 도구 체계에 맞게 조정하세요. 데이터 동작을 담당하는 패키지 안에 models.py 같은 파일을 추가하거나 패키지가 커질 때 확장할 수 있습니다. 명령줄 프로젝트라면 웹 폴더를 생략하고, 데이터베이스 서비스에 연결한다면 로컬 데이터베이스 파일을 생략하세요. 프로젝트가 발전해도 같은 원칙을 유지하세요. 각 디렉터리는 관련 코드나 리소스를 찾는 데 도움이 되어야 합니다.