파이썬으로 전향하고 실제로 즐기게 된 경험
(cesarsotovalero.net)- 최근 AI 개발의 트렌드로 인해 본격적으로 파이썬 학습 및 사용을 시작함
- 데이터 처리, 생태계 발전, 성능 향상 등 파이썬 언어와 도구 체계의 급격한 발전을 체감함
- uv, ruff, pytest, Pydantic 등 최신 개발 도구와 라이브러리를 본인의 워크플로우에 적극 도입함
- 프로덕션 환경과 Jupyter 노트북/스크립트 기반 개발 간의 차이를 줄이기 위한 프로젝트 구조 및 자동화 방안을 적용함
- GitHub Actions, Docker 등을 활용해 CI/CD, 테스트, 인프라 관리를 효율적으로 구축함
파이썬으로의 전향 배경
- 최근 6개월 동안 AI 붐에 힘입어 파이썬 프로그래밍에 더욱 몰입하게 된 경험임
- 예전에는 파이썬을 간단한 스크립트 용도로만 사용했으나, AI 애플리케이션(RAG, 에이전트, 생성형 AI 툴 등) 개발 필요성으로 본격적으로 도입함
- 파이썬은 인간 친화적인 문법과 범용적인 Unix 호환성, 그리고 VSCode 등 현대 에디터와의 통합으로 인해 실용성이 크게 향상됨
파이썬 생태계의 성장 및 도구 발전
- 데이터 처리 및 분석을 위한 풍부한 라이브러리와 툴 생태계가 마련됨
- Cython 등 정적 컴파일러의 지원으로 성능도 크게 개선됨
- 과거의 난해한 문법 요소들(예:
__init__
,__new__
등)은 대부분 감춰졌거나 현대적인 문법으로 대체됨 - 여러 도구 및 환경설정의 변화를 직접 경험하면서 파이썬에 대한 애착과 긍정적 인식을 갖게 됨
파이썬 프로젝트 구조
-
백엔드와 프론트엔드를 통합하는 모노레포 구조를 선호함
- 코드 관리 효율성, 검색 용이성, 단순화된 배포 및 테스트 파이프라인 등을 이유로 단일 저장소를 선택함
- 과도하게 프로젝트를 여러 저장소로 분리하는 것은 오버 엔지니어링의 신호라고 판단함
-
전형적인 프로젝트 구조 예시는 다음과 같음
- .github: GitHub Actions 등 CI/CD 워크플로우
- .vscode: VSCode 환경 설정
- docs: MkDocs 기반 정적 문서 및 사이트
- project-api: 백엔드 및 데이터/노트북/툴/소스코드/테스트 포함
- project-ui: 프론트엔드(React, Next.js 등)
- 리포지토리 루트에 Makefile, docker-compose.yml, .pre-commit-config.yaml 등 핵심 관리 파일 포함
-
프론트엔드는 무거운 데이터 처리를 금지하고 파이썬 기반 백엔드 API에 HTTP 요청을 위임함
-
각 파이썬 모듈 디렉터리는
__init__.py
로 명확히 지정함
주요 파이썬 개발 도구
uv
- Astral에서 제공하는 최신 파이썬 패키지 매니저 및 빌드 도구임
- 의존성 관리, 가상환경 생성, 프로젝트 초기화 등 대부분의 작업을 빠르게 처리함
-
pyproject.toml
이 핵심 설정 파일로, 모든 메타데이터 및 의존성 정보가 통합됨
ruff
- 초고속 파이썬 린터 및 코드 포매터로, isort, flake8, autoflake 기능을 통합 제공함
- PEP 8 코딩 스타일 가이드 기본 지원
ty
- Astral에서 개발 중인 정적 타입 검사기로, typing 모듈과 연계하여 타입 오류를 사전에 탐지함
- 초기 개발 단계임에도 안정적으로 사용할 만한 수준임
pytest
- 단위테스트 및 확장 가능한 테스트 환경을 제공하는 대표적인 파이썬 테스트 프레임워크임
- 간단한 파일 네이밍 규칙과 명령어 한 줄로 바로 통합 테스트 가능함
Pydantic
- 데이터 검증 및 환경 설정 관리 라이브러리임
- application의 다양한 설정값을 타입 기반으로 선언하고, 자동으로 환경 변수나 .env 파일에서 값을 읽어서 검증함
MkDocs
- 파이썬 프로젝트의 정적 웹사이트 및 문서 생성을 간편하게 지원함
- 오픈소스 프로젝트 스타일의 미려한 디자인 빠른 적용 가능함
FastAPI
- RESTful API 개발을 위한 프레임워크로, 자동 검증 및 문서화, 빠른 성능, 쉬운 Pydantic 통합 장점이 있음
- Starlette 및 Pydantic 기반으로 높은 타입 안정성과 성능 제공
Dataclasses
- 파이썬 표준 기능으로 데이터 중심 클래스를 간편하게 정의할 수 있음
- 특별 메소드 자동 생성으로 보일러플레이트 코드 대폭 감소
버전 관리 및 자동화
GitHub Actions
- 다양한 OS에서 CI 파이프라인 구축에 최적화된 워크플로우 제공
- 도커 기반 테스트 환경으로 프로덕션과 동일한 환경에서 테스트 시행 가능
Dependabot
- 자동 의존성 최신화 및 보안 패치 관리를 자동화함
Gitleaks
- 민감 정보(비밀번호, API 키 등) 유출 방지 도구로 git 커밋 전에 보안 검사를 수행함
Pre-commit Hooks
- 커밋 전 자동 린팅, 포매팅, 보안 검사를 위한 도구임
- ruff, gitleaks 등과 함께 사용해 코드 일관성과 품질 유지
인프라 및 CI/CD 환경 관리
Make
- 반복적인 개발·배포 명령을 단축키처럼 정의할 수 있음
- API 및 인프라 레벨에서 Makefile 분리 관리(예:
make test
,make infrastructure-up
)
Docker & Docker Compose
- 컨테이너 기반 패키징 및 멀티 서비스 오케스트레이션 제공
- Dockerfile에서 의존성 설치·코드 복사·서비스 기동 방식 명확히 정의
- docker-compose.yml로 여러 서비스를 네트워크로 연결하고 환경변수, 볼륨 등을 통합 관리
마무리
위와 같이 최신 파이썬 개발 환경에서는 효율적이고 견고한 프로덕션 워크플로우를 구성할 수 있음
AI, 데이터, 웹 개발 등 다양한 영역에 걸쳐 파이썬 생태계의 성장과 도구 발전으로부터 많은 이점을 경험할 수 있음
모노레포 구조, 자동화 도구, 린터 및 타입 검사기, 즉각적인 테스트 환경, 문서화, 인프라 오케스트레이션까지 하나의 통합된 개발 문화를 구현할 수 있음
Hacker News 의견
-
코드에서 환경변수 누락 시 “YOUTUBE_API_KEY 또는 YOUTUBE_CHANNEL_ID가 없습니다”라고 OR로 메시지를 띄우는 방식은 굳이 OR를 쓸 필요 없는 상황에서 사용자를 괴롭히는 것임. 각각의 값을 개별적으로 체크해 어떤 것이 빠졌는지 명확히 알려주는 것이 훨씬 좋은 사용자 경험임. 개발 시간 차이도 거의 없다는 점에서 이렇게 하는 걸 추천함
-
작은 부분까지 집요하게 파고드는 이야기지만, 이런 케이스는 := 연산자(월러스 연산자)를 쓰기에 딱 알맞다고 생각함. 예시로, if not (API_KEY := os.getenv("API_KEY")): 처럼 바로 쓸 수 있음. 개인적으로 내부 도구에서는 os.environ["API_KEY"]에서 KeyError를 그냥 터뜨리게 둠. 이 역시 충분히 명확하다고 생각함
-
더 나아가서, 조건을 하나씩 검사해 하나라도 빠진 게 있으면 전부 알려주는 편이 훨씬 낫다고 생각함. 한 변수 누락 때문에 프로그램을 돌리고, 그 다음에 또 다른 변수 에러를 보는 불편함을 줄일 수 있음. 상황에 따라 어쩔 수 없이 번거로울 때도 있지만, 가능한 한 한 번에 보여주는 게 좋음
-
환경변수들을 전부 가져오고, 그 중 빠진 것들을 한 번에 리포트해 주는 방법이 가장 좋음
-
boolean 플래그를 활용해서 마지막에 한 번만 exit(1) 해버리는 방법도 있음. 이렇게 하면 누락된 환경변수를 한 번에 모두 보여줄 수 있음
-
exit("Missing ...")처럼 메시지를 바로 출력하면서 코드 1로 종료할 수도 있음
-
-
프로젝트 구조를 자동으로 만들어주는 도구를 찾고 있다면 cookiecutter를 추천함. 내가 자주 쓰는 몇 가지 템플릿이 있는데, python-lib, click-app, datasette-plugin, llm-plugin 등이 있음. 다음처럼 사용하면 됨:
uvx cookiecutter gh:simonw/python-lib
-
Ruby로 baker라는 걸 만들었음. baker는 템플릿 repo를 복사하지 않고, 해야 할 작업리스트(명령형 단계 목록)를 만들고, 수동 작업(API key를 받아와 설정하기)과 자동 작업('uv init' 등)을 섞을 수 있음. Markdown 문법에 루비 스트링 인터폴레이션, bash도 쓸 수 있음. yml 베이스 config에 아주 지쳤기 때문에 만들게 된 것임
-
요즘 뜨는 건 Copier라는 도구임. 자세한 건 copier 문서 참고
-
신규 프로젝트 세팅하는 걸 오히려 즐기는 편임. 이런 걸 굳이 자동화하고 싶지 않음
-
이런 구조화 자동화 툴은 사실 요즘 에이전트 기반 LLM 개발 워크플로에도 딱 어울리는 영역이라고 생각함
-
-
"파이썬이 유닉스 대부분에 기본 탑재라서 더 인간 친화적"이라는 평가는 다소 낙관적인 해석임. "import json" 이상만 넘어가면 금방 virtualenv 지옥에 빠지게 됨. Python 3.13.x 환경에서 Ubuntu 22.04나 24.04, Rocky 9 등에서 돌리려면 결국 venv, 컨테이너, 버전매니저는 필수가 됨
-
“import json” 같은 기본 라이브러리조차, 포함되지 않은 언어라면 따로 설치해야 하지만, 파이썬은 표준라이브러리 덕분에 초반 생산성이 높음. 물론 대형 프로젝트에서 표준라이브러리만으론 부족하지만, 실제로 표준라이브러리로만 여러 실전 코드들을 배포했고 배포, 보안 관리 이슈가 생기지 않음. venv 관리도 예전만큼 어렵지 않으며, 패키지 매니저도 발전했음
-
내 농담삼아 주장하는 이론 중 하나는, Docker/컨테이너가 이렇게 빨리 확산된 이유의 절반은 파이썬 의존성 지옥을 극복하게 해줬기 때문임. 내 첫 파이썬 경험은 2012년 서버에 파이썬 서비스 설치였는데, 의존성 지옥, venv 명령어, 다루기 힘든 환경 세팅, 정말 끔찍했음. pip, brew, macOS 환경에서도 삽질만 반복했고, 파이썬만 보면 바로 피했음. 하지만 최근 uv 덕분에 초보자 입장에서도 파이썬이 한결 나아졌다고 느낌. uv init, uv add, uv run 만으로도 충분함
-
virtualenv는 늘 써야 한다고 생각함. 결국 하나의 디렉토리일 뿐이고, 이제 pip로 시스템 전체에 설치하려 하면 경고도 뜨는 등, 예전만큼 어렵지 않음
-
virtualenv나 container를 꼭 쓰는 게 좋음. 다루기 어렵게 느껴져도, 업데이트나 라이브러리 버전 업 때문에 시스템 전체에 영향 주는 일을 피할 수 있음
-
예전엔 시스템에 Python2만 기본 포함된 경우가 많았고, 시스템 자체가 이 Python2에 의존할 때도 있어서 오히려 위험했음
-
-
파이썬이 동시에 장황하면서도 부족하다고 느껴짐. 뭔가 간단한 거 하려면 500개씩 의존성을 넣거나, 아니면 아주 사소한 일에도 수십부터 많게는 수백 줄까지 코드가 늘어나게 됨. 그래서 파이썬은 불필요한 삽질이 너무 많아 피하게 됨. Perl로 훨씬 빠르고 간결하게 마무리할 수 있어서 Perl을 선호함. 파이썬은 무언가 일 자체보단 프로그래밍을 위한 프로그래밍 같아짐
-
난 의존성 없는 프로젝트도 많이 만듦. 표준라이브러리와 단일 파일로도 진짜 많은 걸 할 수 있음. Python만 깔려 있다면 curl로 바로 내려서 돌릴 수 있음. 예로 2000줄짜리 돈 관리 CLI 툴이 있는데, plutus는 12개 정도 표준 모듈만 씀. 코드 중 25% 가량이 argparse로 커맨드 파싱하는 부분임. 파라미터별로 라인 하나씩 두는 식으로, 명확하게 쓰는 걸 좋아함
-
Perl이 Python보다 빠르고 강력하다고 했는데, 구체적으로 어떤 예시가 있는지 궁금함
-
파이썬은 데이터구조 중첩할 때 머리 안 쓰고 바로 쓸 수 있다는 점이 편함. 리스트 안 튜플, 딕셔너리 등 자유롭게 섞을 수 있고 통일된 문법으로 접근 가능함. Perl은 분명 더 똑똑하고 재미있긴 한데, 그래서 오히려 머릿속이 꼬이기 쉬워 내게는 별로임. Python은 심심하긴 한데 5년 뒤 봐도 이해할 수 있게끔 명확성이 상당히 큼
-
파이썬은 표준라이브러리로도 충분히 쓸 만하다고 생각함
-
-
나는 모노레포 구조 선호자지만, 예전에 다녔던 회사에서는 이 방식 때문에 초대형 비대한 구조가 되어 다른 팀 코드를 잘못 건드릴까봐 아무도 손대지 않게 된 경우가 있었음. 이슈의 핵심은 레포 자체가 아니라, requirements.txt를 레포 전체 하나로 관리하거나 빌드 스크립트가 꼬인 탓이 큼. 이론상 한 번만 의존성 업데이트하면 모든 코드가 최신 패치로 안전해져야 하는데, 현실에서 이를 누구도 건들지 못했음. 모노레포는 조직이 매우 NIH(Google처럼 직접 모든 걸 만드는 성향)일 때만 잘 굴러감. 이런 경험 덕에, 각 서비스가 조직의 팀 구조와 일치하는 마이크로서비스 구조를 오히려 높게 보기 시작함. Conway's law도 참조해볼 만함
-
파이썬은 내가 쓴 의사코드에 가장 근접하게 동작하는 언어임. 머릿속에서 명확하다고 넘어가는 부분마다 실제로도 파이썬이 직관적인 추상화를 제공해줌. 수학 기반 백그라운드에서 왔기에 참 만족스럽게 다가왔음. 물론 지금은 다른 언어들도 좋아하지만 여전히 매력이 있음
- 수학적 사고를 하는 사람 입장에서는 OOP 쪽이 오히려 사고를 어렵게 만듦. 등가적 추론, 더 좋은 람다, 부작용 회피, 데이터 불변 등이 중요함. OOP는 내가 접한 패러다임 중 수학과 가장 거리가 멀게 느껴짐
-
거의 똑같은 패턴으로 프로젝트 구성을 만들고 있음. 너무 비슷해서 소름끼칠 정도임. Python 개발자 생태계가 점점 비슷한 스타일로 수렴하는 게 아닌가 생각함. 예전엔 내 선택이 독특한 줄 알았는데, 이렇게 다들 같은 방식이면 내 자유의지는 어디 갔나 싶음. 흔한 아기 이름 짓는 현상과 비슷하게, 독특하다고 생각한 선택이 사실은 인기 #2였던 느낌임
-
이런 구조는 10년 전부터 파이썬에서 인기가 있었음. 결국 여러 합리적인 엔지니어가 고민 끝에 이 패턴에 자연스럽게 모이는 것 같음
-
사람의 에고가 마치 파일럿파 양자파처럼 모든 스펙트럼에 깔려 있고, 거기서 존재로 변화한다는 느낌이 듦. becoming-being, 웃음이 절로 남
-
-
다른 사람도 파이썬을 좋아하게 된 걸 보면 반갑게 느껴짐. 나는 원래 Ruby를 선호했지만 고객의 요구로 파이썬을 어쩔 수 없이 쓰게 됐음. 예전에는 Ruby가 많이 느렸으나, 억지로 파이썬을 익히면서 점점 익숙해졌고, 지금은 나름 즐기고 있음. Make 사용법에 대해선 다소 이견이 있는데, 의존성을 전혀 쓰지 않는다면, 케이스 문 들어간 스크립트랑 다를 게 없음... 농담 반 섞어서 말하지만, 요즘 세대는 Make에 익숙하지 않은 걸 보면 씁쓸함. 나 때는 말이야, 라는 심정임
-
Ruby는 문법이 훨씬 예쁨. 들여쓰기만으로 스코프를 구분하는 파이썬은 내 스타일이 아님
-
처음엔 케이스 문으로 된 스크립트로 시작했다가, 결국 flat한 Makefile로 진화했음. Makefile이 더 표준적이고 무작위 스크립트보다 알아보기 쉬움
-
-
Dataclass와 Pydantic Basemodel 중 어떤 걸 써야 할지 궁금함. Pydantic을 이미 쓴다면 그냥 다 Pydantic으로 통일해도 되지 않을까 싶은데, 굳이 Dataclass를 쓸 이유가 있을지 고민임
-
attrs 프로젝트에서 매우 잘 정리해둔 비교글이 있음. attrs 공식 비교가 있는데, 물론 약간의 편향은 있겠지만 논리적 근거는 충분하다고 생각함. 또 이 블로그도 도움이 됨
-
Dataclass는 nested object 검증을 지원하지 않음. 그래서 단순하게 함수 인자 전달용 flat 구조에는 dataclass를 쓰는 게 나음. 너무 많은 인자를 리스트로 받는 것보다 명확함
-
생성 시 데이터 검증 때문에 성능 저하 이슈가 있음. msgspec처럼 훨씬 가볍고 빠른 대안도 있음
-
굳이 검증이나 직렬화가 필요 없으면 Pydantic은 오히려 쓸데없는 오버헤드임. 내 원칙은 직렬화가 필요하면 Pydantic, 아니면 dataclass
-
TypeAdapter(MyDataclass)
처럼 기존 dataclass를 바로 쓸 수 있는데, 굳이 Pydantic 모델을 따로 만들 이유가 있나 싶음
-
-
최근에는 오히려 Python이 아니라 다른 언어로 이주해서 더 만족하고 있음. 내 파이썬에 대한 생각은 이 글에 정리해놨음. 다음에 다시 파이썬 쓸 기회가 온다면 uv, ruff, ty 같은 걸 꼭 써 볼 생각임
- 나 역시 백엔드에서 Python에서 JS로 갈아타고 한참 즐기고 있음. 파이썬 설치/패키지 관리가 망가진 건 동의함. 하지만 나에겐 async가 제일 큰 생산성 향상이었음. Python에는 asyncio가 있지만, 여러 경쟁 방식이 혼재되어 표준이 안 잡혀 있음. JS는 딱 하나에 모인 점이 좋아서 훨씬 편했음. 자잘한 항목도 다 합치면 큰 차이를 만들었고, 파이썬은 들여쓰기 스코핑, 임포트에서 상대경로 문제, JS 객체 문법 등 여러 부분이 더 쾌적함. 관련 설명 참고