Rain Lag

첫 번째 실전 Python 앱 설계도: 일회용 스크립트에서 탄탄한 프로젝트로

작은 Python 스크립트를 실제 서비스에 쓸 수 있는 구조적인 애플리케이션으로 발전시키는 방법을, 실용적인 단계와 베스트 프랙티스, 명확한 학습 경로와 함께 정리했습니다.

첫 번째 실전 Python 앱 설계도: 일회용 스크립트에서 탄탄한 프로젝트로

Python이 유명한 이유 중 하나는 시작이 정말 쉽다는 점입니다. 몇 줄만 쓰고 실행하면 바로 뭔가 동작합니다. 이 즉각적인 피드백은 굉장히 강력하죠. 하지만 어느 순간부터는 작은 실험을 넘어서, “진짜” 애플리케이션처럼 느껴지는 것을 만들고 싶어질 겁니다.

그렇다면 print("Hello, world") 수준에서 출발해, 6개월 뒤에 내가 다시 봐도, 다른 사람에게 보여줘도 부끄럽지 않은 깔끔하고 정리된 프로젝트로 어떻게 나아갈 수 있을까요?

이 글은 그 과정을 위한 실전 설계도를 제공합니다. 일회용 스크립트로 시작해서, 점차 구조와 패턴, 도구들을 더해 가며 실제 현업에서도 쓸 수 있는 탄탄한 Python 앱으로 키우는 방법입니다.


1. 첫 실전 앱으로 Python이 딱 좋은 이유

Python은 애초에 입문자가 쓰기 쉽게 설계되었습니다.

  • 읽기 쉬운 문법: 코드가 마치 영어 문장처럼 자연스럽게 보입니다.
  • 배터리 포함(batteries included): 표준 라이브러리만으로도 파일, 웹 요청, 데이터 처리 등 꽤 많은 걸 할 수 있습니다.
  • 거대한 생태계: 웹 앱(Django, Flask, FastAPI), 데이터 분석(Pandas, NumPy), 자동화(Requests, Selenium) 등 거의 모든 분야에 라이브러리가 있습니다.

이 말은 곧, 다음과 같은 것이 가능하다는 뜻입니다.

  • 아주 단순한 아이디어에서 시작하고
  • 금방 동작하는 프로그램으로 만들고
  • 기존 걸 다 버리지 않고도 점점 발전시킬 수 있습니다.

핵심은 지저분한 초보 단계(“막 코딩하는 시기”)를 건너뛰려 하지 않는 것입니다. 대신 그 시기를 의도적으로 활용해서 다음 단계로 넘어가는 발판으로 삼는 겁니다.


2. 1단계: 일회용 스크립트를 기꺼이 활용하라

**일회용 스크립트(throwaway script)**란, 길지 않은 한 파일짜리 프로그램으로, 장기 유지보수를 염두에 두지 않은 코드입니다. 걸작이 아니라, 연습장이라고 생각하면 됩니다.

예를 들면 이런 것들입니다.

  • 폴더 안의 파일 이름을 일괄 변경하는 스크립트
  • API에서 날씨 데이터를 가져와 출력하는 작은 프로그램
  • 특정 CSV 파일을 한 번 정리/정제하기 위한 스크립트

이런 것들이 왜 유용할까요?

  • 피드백이 빠르다: 복사, 실행, 수정, 재실행 사이클이 빠릅니다. 바꾼 게 바로 보입니다.
  • 압박이 덜하다: “못생긴 코드”여도 괜찮습니다. 학습용이지, 바로 서비스에 올릴 코드는 아니니까요.
  • 학습이 집중된다: 각 스크립트마다 반복문, 함수, 파일 I/O, HTTP 요청 등 하나의 개념에 집중해서 연습할 수 있습니다.

초기 스크립트는 대략 이런 느낌일 수 있습니다.

# weather_script.py import requests response = requests.get("https://wttr.in/London?format=3") print("Weather:", response.text)

이 정도면 시작으로는 충분합니다. 하지만 이런 스크립트에 코드를 계속 덕지덕지 붙이다 보면, 한 파일에 모든 게 쌓이면서 금세 고통스러워집니다. 그때가 바로 **“이제 레벨업할 때”**라는 신호입니다.


3. 스크립트에서 “진짜 앱”으로: 크기보다 구조가 중요하다

실전 앱을 가르는 기준은 코드 줄 수가 아닙니다. 핵심은 **구조(structure)**입니다.

  • 한눈에 무엇을 하는 프로그램인지 이해할 수 있는가?
  • 한 부분을 고쳐도 다른 곳이 덩달아 깨지지 않고 변경할 수 있는가?
  • 다른 사람이 사용하거나 기능을 확장하기 쉬운가?

스크립트를 앱으로 키워 가는 데서 중요한 건 “기능을 더 붙이는 것”이 아니라, 구조를 도입하는 것입니다.

초기에 적용할 수 있는 구조적 업그레이드 세 가지:

  1. 긴 상단(top-level) 코드를 함수로 분리한다.
  2. 역할을 나눈다. 예: **데이터 가져오기(fetch)**와 **출력 형식 만들기(format)**를 분리.
  3. 한 파일에 담기 버거워지면, 모듈과 패키지로 코드를 나눈다.

예를 들어, 날씨 스크립트를 이렇게 리팩터링할 수 있습니다.

# app.py import requests def fetch_weather(location: str) -> str: url = f"https://wttr.in/{location}?format=3" response = requests.get(url, timeout=5) response.raise_for_status() return response.text def main(): location = "London" weather = fetch_weather(location) print(f"Weather in {location}: {weather}") if __name__ == "__main__": main()

이것만으로도 꽤 많이 좋아졌습니다.

  • fetch_weather는 재사용 가능하고 테스트하기도 쉬운 함수입니다.
  • main이 진입점(entry point) 역할을 하니, 어디서부터 읽기 시작해야 할지 명확해집니다.
  • if __name__ == "__main__": 가드 덕분에 이 파일은 직접 실행도 가능하고(import 시) 다른 곳에서 가져다 쓰기도 좋습니다.

이 작은 변화가 바로, 실제 애플리케이션의 씨앗입니다.


4. 핵심 프로젝트 구조: 폴더, 모듈, 그리고 관심사의 분리

앱이 커질수록, 새로운 기능을 추가하는 것보다 정리해서 구조화하는 것이 훨씬 중요해집니다. 아래는 간단하면서도 “프로젝트 같다”는 느낌을 주는 구조 예시입니다.

my_weather_app/ ├─ my_weather_app/ │ ├─ __init__.py │ ├─ cli.py │ ├─ weather.py │ └─ config.py ├─ tests/ │ └─ test_weather.py ├─ README.md ├─ pyproject.toml # 혹은 requirements.txt, setup.cfg 등 └─ .gitignore

각 파일/폴더의 역할

  • my_weather_app/ (안쪽 폴더): 이 자체가 패키지입니다.
    • __init__.py: 이 폴더가 패키지임을 알리는 파일입니다. 필요하다면 여기서 상위 레벨 함수들을 노출할 수도 있습니다.
    • cli.py: 커맨드라인 인터페이스(CLI)를 담당합니다. 인자 파싱, 실행 흐름 조율 등.
    • weather.py: 핵심 로직. 날씨 정보를 가져오고, 파싱하고, 변환하는 부분.
    • config.py: 기본값, 환경 변수 읽기, 설정 값 관리 등.
  • tests/: 코드가 조용히 망가지는 것을 막아 주는 자동화 테스트들이 들어갑니다.
  • README.md: 프로젝트가 무엇을 하는지, 어떻게 사용하는지 설명하는 문서입니다.
  • pyproject.toml / requirements.txt: 의존성 및 프로젝트 메타데이터를 정의합니다.

관심사의 분리(Separation of Concerns)를 실제로 적용하기

모든 걸 한 파일에 몰아넣는 대신, 앱을 **레이어(층)**로 나누어 생각해 봅니다.

  • 입출력 레이어(I/O layer): CLI, 웹 API, UI 등 외부와 소통하는 부분
  • 도메인 로직 레이어(domain logic): 실제로 문제를 해결하는 코드 (계산, 데이터 가공/조합 등)
  • 인프라 레이어(infrastructure): 데이터베이스, HTTP 요청, 파일 시스템, 설정 관리 등

이렇게 나누면 프로젝트가 다음과 같이 변합니다.

  • 테스트가 쉬워집니다. 도메인 로직을 실제 API를 호출하지 않고도 테스트할 수 있습니다.
  • 확장이 쉽습니다. CLI로 시작했다가, 같은 로직을 재사용해 웹 API로 바꾸는 것도 훨씬 편합니다.
  • 이해하기가 쉬워집니다. 각 파일이 “무슨 역할을 하는지”가 명확해집니다.

5. 예제로 배우기: 실제 프로젝트를 보고 익혀라

좋은 구조를 처음부터 혼자 발명할 필요는 없습니다. Python 생태계에는 이미 훌륭한 오픈 소스 예제가 넘쳐납니다.

GitHub에서 작지만 잘 정리된 프로젝트들을 살펴보세요. 특히 이런 부분을 주의 깊게 보면 좋습니다.

  • 폴더 구조: 설정 파일, 테스트 코드, 애플리케이션 코드가 어디에 배치되어 있는지
  • 이름 짓기: 모듈, 함수, 클래스 이름을 어떻게 짓는지
  • 진입점: main()이 있는지, 커맨드라인 도구는 어떻게 노출하는지
  • 테스트 구조: 테스트와 픽스처(fixture)를 어떻게 구성하는지

코드를 “프로처럼” 읽기 위한 팁:

  • 처음부터 거대한 프레임워크 수준의 프로젝트 대신, 작은 프로젝트부터 보는 게 좋습니다.
  • 자신이 이해할 수 있는 문제를 다루는 프로젝트(예: CLI 도구, 간단한 웹 API)를 골라 보세요.
  • 먼저 README, CONTRIBUTING, DEVELOPING 같은 문서를 읽어서 전체 그림을 파악합니다.

이건 무작정 베끼는 게 아니라, 패턴을 흡수하는 과정입니다. 숙련된 개발자들이 어떻게 코드를 깔끔하고 확장 가능하며 유지보수하기 좋게 만드는지 감을 얻는 겁니다.


6. 자연스러운 학습 경로: print에서 데이터베이스까지

실력이 늘어날수록, Python 앱은 점점 다양한 외부 시스템과 상호작용하게 됩니다. 아래처럼 단계적인 학습 경로를 생각해볼 수 있습니다.

  1. 기본 스크립트 단계

    • print, 반복문, 조건문, 함수
    • 간단한 파일 읽기/쓰기
  2. CLI 도구 단계

    • argparse, click, typer 등으로 커맨드라인 옵션을 받기
    • 코드를 함수와 모듈로 나눠서 구조화하기
  3. 외부 API & 네트워킹 단계

    • requests로 웹 API 호출하기
    • JSON 응답 파싱하기
    • 에러와 타임아웃 처리하기
  4. 영속 데이터 & 데이터베이스 단계

    • 로컬 파일(JSON, CSV, SQLite)로 데이터 저장해 보기
    • SQLAlchemy 같은 라이브러리로 PostgreSQL, MySQL 등 진짜 DB에 연결해 보기
  5. 웹 앱 또는 서비스 단계

    • Flask/FastAPI/Django 등을 사용해 웹 애플리케이션 만들기
    • 라우트, 모델, 템플릿을 구조화해서 관리하기

각 단계는 조금씩 복잡해지지만, 앞에서 다진 **조직화 스킬(함수, 모듈, 레이어, 테스트)**은 모든 단계에 그대로 이어집니다.


7. ‘막 짜기’에서 ‘설계하기’로: 핵심 마인드셋 전환

스크립트를 탄탄한 프로젝트로 키우는 일은 코드만의 문제가 아니라 생각하는 방식의 변화이기도 합니다. 중요한 전환 몇 가지를 정리해 보면:

  1. “일단 돌아가게”에서 “명확하게”로
    돌아가는 코드만으로는 충분하지 않습니다. “내가 3개월 뒤에 이 코드를 봐도 이해할 수 있을까?”를 항상 스스로에게 물어보세요.

  2. “복붙”에서 “추출 & 재사용”으로
    비슷한 로직이 여러 번 반복된다면, 함수나 클래스로 추출해서 재사용하는 습관을 들이세요.

  3. “전역으로 다 공유”에서 “명확한 인터페이스”로
    전역 변수 남발을 줄이고, 함수 매개변수와 반환값을 통해 데이터를 전달하세요. 구현 세부사항은 함수/모듈 안에 숨기고, 깔끔한 인터페이스만 외부에 드러내는 것이 좋습니다.

  4. “수동 테스트”에서 “자동화 테스트”로
    핵심 로직부터라도 간단한 테스트를 붙여 보세요. 몇 개 안 되는 테스트라도 치명적인 버그를 초기에 막는 데 큰 도움이 됩니다.

  5. “한 파일”에서 “모듈형 프로젝트”로
    파일이 너무 길거나, 한 파일이 너무 많은 일을 한다면, 역할에 따라 모듈을 나누는 시그널입니다.

이런 습관들이 금방 잊히는 급조 스크립트오래 버틸 수 있는 애플리케이션을 가르는 차이입니다.


8. 오늘 바로 따라 할 수 있는 간단한 설계도

다음에 무언가 아이디어가 떠오르면, 아래 과정을 그대로 따라가 보세요.

  1. 일회용 스크립트로 시작한다.
    한 파일에서 최소 기능만 빨리 구현해 보세요. 처음부터 너무 고민하지 말고, 일단 돌아가게 만드세요.

  2. 함수로 리팩터링한다.
    논리적으로 한 덩어리인 부분들을 찾아, 이름이 잘 붙은 함수로 분리합니다.

  3. main()과 진입점을 도입한다.
    if __name__ == "__main__": main() 패턴을 사용해, 스크립트가 직접 실행도 되고, 다른 코드에서 import도 가능한 구조로 만듭니다.

  4. 패키지로 승격시킨다.
    폴더를 만들고 __init__.py를 추가한 뒤, 로직을 core.py, cli.py 같은 모듈로 나누어 옮깁니다.

  5. 기본 테스트를 추가한다.
    tests/ 폴더를 만들고, 핵심 로직에 대한 간단한 테스트 몇 개만이라도 작성해 보세요.

  6. 사용법을 문서화한다.
    README.md에 이 앱이 무엇을 하는지, 어떻게 설치/실행하는지 간단히 적습니다.

  7. 계속 반복 개선한다.
    복잡도가 커질수록, 역할을 더 잘 쪼개고, 함수는 더 단순하게 유지하고, 인터페이스는 더 명확하게 다듬어 나가세요.

이 설계도를 파일 이름 바꾸기 도구, API 클라이언트, 간단한 대시보드 등 여러 아이디어에 반복해서 적용하다 보면, 자연스럽게 “좋은 구조가 어떤 느낌인지” 몸으로 익히게 됩니다.


맺음말: 첫 실전 앱은 생각보다 훨씬 가까이 있다

“진짜” Python 앱을 만들기 위해 거창하고 복잡한 아이디어가 꼭 필요한 것은 아닙니다. 필요한 것은 다음 네 가지입니다.

  • 작지만 현실적인 문제 하나
  • 출발점이 되는 간단한 일회용 스크립트
  • 함수, 모듈, 패키지, 테스트로 이어지는 점진적인 구조 개선
  • 실제 프로젝트들에서 패턴을 관찰하고 적절히 가져오는 태도

목표는 단지 코드를 “돌아가게” 만드는 것이 아닙니다. 시간이 지나도 계속 키워 나갈 수 있는 견고하고, 재사용 가능하며, 잘 조직된 프로젝트를 만드는 것입니다.

이미 만들어 둔 작은 스크립트 하나를 떠올려 보세요. 이 글의 설계도를 따라, 그것을 작은 앱으로 바꿔 보세요. 그렇게 하나씩 쌓아 가는 과정에서, 당신은 “그때그때 급하게 짜 넣는 스크립트 작성자”에서 Python 개발자처럼 생각하고, 설계하고, 만드는 사람으로 자연스럽게 변해 있을 것입니다.

첫 번째 실전 Python 앱 설계도: 일회용 스크립트에서 탄탄한 프로젝트로 | Rain Lag