작성자가 말한 “pip vs poetry vs uv 신경 안 씀” 부분은 사실 uv가 이 사용 사례를 직접 지원함
PyPI 의존성까지 포함해서, Python 버전과 uv만 설치되어 있으면 됨 uv 공식 문서 링크
이보다 더 나은 방법도 있음 #!/usr/bin/env -S uv run --python 3.14 --script
이렇게 하면 Python 자체가 설치되어 있지 않아도 uv가 지정된 버전을 내려받아 실행함
나도 그렇게 생각했지만, 비-Python 사용자에게는 아직 직관적이지 않음
Clojure를 처음 접하면 대부분 Leiningen을 쓰라는 조언을 듣지만, Python은 검색하면 venv, poetry, hatch, uv 등 여러 가지가 나옴
uv가 점점 대세가 되어가고 있지만 아직은 보편적이지 않음
예전에 Go를 apt로 설치했다가 버전이 너무 오래돼서 다시 설치했던 경험이 있는데, 그건 훨씬 빨리 해결됐음
Python의 가상환경 문제는 여전히 복잡함
나는 2019년에 PyFlow로 이 문제를 해결했었음
Rust로 작성된 OSS 도구로, Python 버전과 venv를 자동 관리함 pyproject.toml만 설정하고 pyflow main.py를 실행하면 Cargo처럼 의존성을 설치하고 잠그며, 프로젝트에 맞는 Python 버전도 자동으로 맞춰줌
당시에는 Poetry와 Pipenv가 인기였지만, venv와 버전 관리까지는 부족했음
나도 대부분 uv로 옮겨감 uv add를 주로 쓰고, 필요할 때만 uv pip를 씀
하지만 uv pip는 pip의 한계를 그대로 가짐 — 설치 순서에 따라 의존성 해석이 달라짐 uv pip install dep-a 후 dep-b를 설치하는 것과 순서를 바꾸는 것, 혹은 한 번에 설치하는 것이 다 다름
이는 pip의 문제에 가깝지만, Python 패키지 관리의 혼란은 여전함
사실 Python 버전조차 지정할 필요 없음
uv가 알아서 내려받음
Go는 shebang 지원을 명시적으로 거부했음
대신 gorun을 쓰는 게 권장됨 /// 2>/dev/null ; gorun "$0" "$@" ; exit $? 같은 POSIX 트릭으로 실행 가능함
Nim, Zig, D는 -run 옵션으로 비슷하게 쓸 수 있고, Swift, OCaml, Haskell은 파일을 직접 실행할 수 있음 관련 토론 링크
작은 스크립트에는 go run 대신 yaegi 인터프리터가 더 나을 수도 있음 yaegi GitHub
“pip, poetry, uv 차이를 알고 싶지 않다, 그냥 코드만 실행하고 싶다”는 글은 결국 기술 숙련도 문제임 uv run과 PEP 723이 이미 모든 문제를 해결했음
맞음, 하지만 uv run이 나오기까지 너무 오래 걸렸음
20년 넘게 Python을 써왔지만, 외부 패키지나 venv가 있는 코드베이스는 항상 두려웠음 uv run 덕분에 회사 프로젝트는 모두 옮겼지만, 개인 프로젝트는 이미 Go로 넘어감
장기적으로는 정적 타입 언어를 선호함
오래된 언어라면 결국 경쟁 라이브러리를 배우게 됨
이건 UX 문제임
사용자는 그냥 프로그램이 실행되길 원함 uv run과 PEP 723이 문제를 해결했지만, uv를 알아야 한다는 점에서 여전히 진입장벽이 있음
uv가 공식 기본 도구가 아닌 이상, 많은 사용자가 Python을 떠날 것임
정말 천재적인 아이디어라고 생각함
하지만 스크립팅은 배포용 소프트웨어와는 다른 인체공학적 감각이 필요함
bash는 즉흥적이고, Go는 제품화에 적합하며, Python은 그 중간쯤, Ruby는 bash에 가깝고, Rust는 Go 쪽임
스크립트는 OS 명령어를 빠르게 조합해 일회성 작업을 처리할 때 유용함
Go는 그런 즉흥성이 부족함
나도 Python이 “중간쯤”이라는 말에 공감함
Debian에서 간단한 gtk 앱을 uv로 실행하려 했는데, 의존성은 다 맞는데도 실행이 안 되고 결국 Core Dump
Python을 새로 시도할 때마다 이런 일이 반복됨
Go는 장황하지만, 한 번 컴파일되면 그냥 동작함
나도 비슷하게 느낀다
핵심은 한 파일로 끝낼 수 있느냐임
Go로도 500줄짜리 스크립트는 가능하지만, 언어 자체가 여러 파일과 모듈을 전제로 함
bang-line이 안 되는 것도 그런 이유임
어차피 go run이 임시 바이너리를 만드는 구조라면, 그냥 빌드해서 /usr/local/bin에 넣는 게 낫다고 봄
bash가 OS 명령어에 더 가깝다는 말은 오해임
bash도 Python만큼이나 OS 위의 추상 계층일 뿐, 단지 기본 셸이라 그렇게 느껴질 뿐임
LLM이 코드를 대신 수정해주는 시대라면, 작성 인체공학보다 가독성이 더 중요해질 수도 있음
특히 LLM이 쓴 코드를 사람이 읽기 쉽게 만드는 방향으로
Python을 처음 접하는 사용자가 pip, poetry, uv 차이를 몰라도 된다는 점에는 동의함
하지만 이런 주제로 글을 쓰는 블로거라면 최소한 uv가 문제를 해결한다는 사실 정도는 알아야 함
무지한 비판은 설득력이 없음
uv가 Go처럼 “write once, run anywhere”를 해결하냐는 질문이 있음
나도 uv의 개념을 완전히 이해하지 못했기에 궁금함
나는 Python으로 스크립트 짜는 걸 좋아함
빠르게 작업할 수 있고, 타입이나 메모리 걱정 없이 단순한 일을 처리하기 좋음
하지만 대규모 애플리케이션에는 쓰고 싶지 않음
나도 Python 스크립팅은 좋아하지만, 남의 스크립트를 설치하는 건 싫음
이건 Linux 중심의 접근임
대부분 시스템에 기본 Python이 있어서 간단한 스크립트엔 충분함
Go를 설치해야 하는 점을 생각하면, 차라리 uv로 Python을 쓰는 게 낫다고 봄
글쓴이도 “약간 트롤링으로 시작했다”고 했듯, 결국 Go 선호의 문제임
JS도 스크립트 언어로 나쁘지 않다고 생각함 node bla.js면 끝임
타입은 항상 신경 써야 함
함수가 뭘 반환하는지 알아야 하고, 언어를 잘 알면 기본 타입은 기억으로 처리함
이건 정적 타입 언어도 마찬가지임
Python은 개발자에게는 훌륭하지만, 배포나 통합에는 악몽임
다른 사람을 고려한다면 Python으로 배포용 코드를 쓰지 말아야 함
기대했던 건 Python 비판이었는데, 오히려 유용한 팁이었음 //를 주석으로 쓰는 언어라면 이 트릭을 응용할 수 있음
C/C++, Java, JavaScript, Rust, Swift, Kotlin, ObjC, D, F#, GLSL 등 가능함
특히 GLSL로 단일 파일 그래픽 데모를 만드는 게 흥미로움 Shadertoy 예시
C에서는 블록 주석을 이용해 /*/../usr/bin/env gcc "$0" "$@"; ./a.out; rm -vf a.out; exit; */ 같은 방식으로도 가능함
Swift에는 외부 의존성을 가진 스크립트를 실행할 수 있는 swift-sh 프로젝트가 있음
Swift용 uv 같은 개념임
Swift는 shebang도 공식 지원함
C/C++에서는 #!을 직접 써도 됨
예전 TCC 시절에 “C 스크립팅”으로 이런 방식을 썼음
큰 프로젝트에서는 빌드 스크립트가 매니페스트를 읽고 빌드 후 실행하는 구조였음
하지만 환경 제어가 어려워서 실무에는 부적합함
Rust는 이런 꼼수를 쓸 필요 없음
shebang을 직접 지원함
더 인체공학적인 언어를 원한다면 .NET 10의 “run file directly” 기능도 있음
shebang을 지원하고, 스크립트 내에서 패키지를 자동 설치함 #:sdk 지시어로 웹앱도 바로 실행 가능함
나도 오늘 처음 이 기능으로 C# 스크립트를 작성했는데, 꽤 괜찮은 경험이었음
다만 AOT 컴파일은 아직 거칠음
처음엔 Python 비판일 줄 알았는데, 오히려 언어 생태계의 방향성을 생각하게 됨
ML이 Python에 묶인 건 큰 실수라고 봄
느리고, 타입 시스템이 불편하며, 배포가 어렵기 때문임
이제는 TypeScript, Go, Rust 같은 대안을 고려해야 함
동의함
다만 ML이 Python을 택한 이유는 C 기반 FFI 때문임
NodeJS나 Rust, Go는 FFI가 약함
Python은 여기서 강점을 가짐
이상적인 건 Python처럼 간단하지만 더 나은 타입 시스템과 배포 체계를 가진 언어임
TypeScript로 대체하자는 건 동의 못함
JS 생태계에서 나온 언어로 Python을 대체하고 싶진 않음
ML이 Python으로 간 건 시장 압력 때문임
Lisp이나 Lua(Torch)가 더 적합했지만, 단순함 때문에 Python이 선택됨
나도 Lisp 기반의 ML 프레임워크를 개발 중이지만, 채택은 어려울 것 같음
Python의 의존성 지옥은 여전히 심각함
버전 호환성 문제, semver 부재, 불안정한 생태계 등으로 인해 JS보다 뒤처진 느낌임
JS/Node는 지난 10년간 성숙했지만 Python은 여전히 2012년에 머물러 있음
ML이 Python에 표준화된 건 정말 아쉬움
나는 단순하고 표현력 있으면서 강타입 + 네이티브 컴파일되는 언어를 원함
CLI 도구를 만들 때 Python보다 Go가 훨씬 빠름
LOC 차이 때문에 Python으로 돌아오긴 했지만, 실행할 때마다 Go가 그립음
아마 OCaml이 이상적이지만, 구식 툴링이 부담스러움
Go 스크립트의 문제는 첫 줄에 공백이 없어야 한다는 점임 gopls가 자동 포맷팅을 강제하기 때문임
CI에서도 포맷 일관성을 유지해야 하므로, 이건 실무적으로 중요함
하지만 더 큰 문제는 go.mod를 쓸 수 없다는 것임
즉, 의존성 버전을 지정할 수 없어 호환성 보장이 약해짐
Hacker News 의견들
작성자가 말한 “pip vs poetry vs uv 신경 안 씀” 부분은 사실 uv가 이 사용 사례를 직접 지원함
PyPI 의존성까지 포함해서, Python 버전과 uv만 설치되어 있으면 됨
uv 공식 문서 링크
#!/usr/bin/env -S uv run --python 3.14 --script이렇게 하면 Python 자체가 설치되어 있지 않아도 uv가 지정된 버전을 내려받아 실행함
Clojure를 처음 접하면 대부분 Leiningen을 쓰라는 조언을 듣지만, Python은 검색하면 venv, poetry, hatch, uv 등 여러 가지가 나옴
uv가 점점 대세가 되어가고 있지만 아직은 보편적이지 않음
예전에 Go를 apt로 설치했다가 버전이 너무 오래돼서 다시 설치했던 경험이 있는데, 그건 훨씬 빨리 해결됐음
Python의 가상환경 문제는 여전히 복잡함
Rust로 작성된 OSS 도구로, Python 버전과 venv를 자동 관리함
pyproject.toml만 설정하고pyflow main.py를 실행하면 Cargo처럼 의존성을 설치하고 잠그며, 프로젝트에 맞는 Python 버전도 자동으로 맞춰줌당시에는 Poetry와 Pipenv가 인기였지만, venv와 버전 관리까지는 부족했음
uv add를 주로 쓰고, 필요할 때만uv pip를 씀하지만
uv pip는 pip의 한계를 그대로 가짐 — 설치 순서에 따라 의존성 해석이 달라짐uv pip install dep-a후dep-b를 설치하는 것과 순서를 바꾸는 것, 혹은 한 번에 설치하는 것이 다 다름이는 pip의 문제에 가깝지만, Python 패키지 관리의 혼란은 여전함
uv가 알아서 내려받음
Go는 shebang 지원을 명시적으로 거부했음
대신
gorun을 쓰는 게 권장됨/// 2>/dev/null ; gorun "$0" "$@" ; exit $?같은 POSIX 트릭으로 실행 가능함Nim, Zig, D는
-run옵션으로 비슷하게 쓸 수 있고, Swift, OCaml, Haskell은 파일을 직접 실행할 수 있음관련 토론 링크
go run대신 yaegi 인터프리터가 더 나을 수도 있음yaegi GitHub
“pip, poetry, uv 차이를 알고 싶지 않다, 그냥 코드만 실행하고 싶다”는 글은 결국 기술 숙련도 문제임
uv run과 PEP 723이 이미 모든 문제를 해결했음uv run이 나오기까지 너무 오래 걸렸음20년 넘게 Python을 써왔지만, 외부 패키지나 venv가 있는 코드베이스는 항상 두려웠음
uv run덕분에 회사 프로젝트는 모두 옮겼지만, 개인 프로젝트는 이미 Go로 넘어감장기적으로는 정적 타입 언어를 선호함
사용자는 그냥 프로그램이 실행되길 원함
uv run과 PEP 723이 문제를 해결했지만, uv를 알아야 한다는 점에서 여전히 진입장벽이 있음uv가 공식 기본 도구가 아닌 이상, 많은 사용자가 Python을 떠날 것임
정말 천재적인 아이디어라고 생각함
하지만 스크립팅은 배포용 소프트웨어와는 다른 인체공학적 감각이 필요함
bash는 즉흥적이고, Go는 제품화에 적합하며, Python은 그 중간쯤, Ruby는 bash에 가깝고, Rust는 Go 쪽임
스크립트는 OS 명령어를 빠르게 조합해 일회성 작업을 처리할 때 유용함
Go는 그런 즉흥성이 부족함
Debian에서 간단한 gtk 앱을 uv로 실행하려 했는데, 의존성은 다 맞는데도 실행이 안 되고 결국 Core Dump
Python을 새로 시도할 때마다 이런 일이 반복됨
Go는 장황하지만, 한 번 컴파일되면 그냥 동작함
핵심은 한 파일로 끝낼 수 있느냐임
Go로도 500줄짜리 스크립트는 가능하지만, 언어 자체가 여러 파일과 모듈을 전제로 함
bang-line이 안 되는 것도 그런 이유임
어차피
go run이 임시 바이너리를 만드는 구조라면, 그냥 빌드해서/usr/local/bin에 넣는 게 낫다고 봄bash도 Python만큼이나 OS 위의 추상 계층일 뿐, 단지 기본 셸이라 그렇게 느껴질 뿐임
특히 LLM이 쓴 코드를 사람이 읽기 쉽게 만드는 방향으로
Python을 처음 접하는 사용자가 pip, poetry, uv 차이를 몰라도 된다는 점에는 동의함
하지만 이런 주제로 글을 쓰는 블로거라면 최소한 uv가 문제를 해결한다는 사실 정도는 알아야 함
무지한 비판은 설득력이 없음
나도 uv의 개념을 완전히 이해하지 못했기에 궁금함
나는 Python으로 스크립트 짜는 걸 좋아함
빠르게 작업할 수 있고, 타입이나 메모리 걱정 없이 단순한 일을 처리하기 좋음
하지만 대규모 애플리케이션에는 쓰고 싶지 않음
대부분 시스템에 기본 Python이 있어서 간단한 스크립트엔 충분함
Go를 설치해야 하는 점을 생각하면, 차라리 uv로 Python을 쓰는 게 낫다고 봄
글쓴이도 “약간 트롤링으로 시작했다”고 했듯, 결국 Go 선호의 문제임
node bla.js면 끝임함수가 뭘 반환하는지 알아야 하고, 언어를 잘 알면 기본 타입은 기억으로 처리함
이건 정적 타입 언어도 마찬가지임
다른 사람을 고려한다면 Python으로 배포용 코드를 쓰지 말아야 함
기대했던 건 Python 비판이었는데, 오히려 유용한 팁이었음
//를 주석으로 쓰는 언어라면 이 트릭을 응용할 수 있음C/C++, Java, JavaScript, Rust, Swift, Kotlin, ObjC, D, F#, GLSL 등 가능함
특히 GLSL로 단일 파일 그래픽 데모를 만드는 게 흥미로움
Shadertoy 예시
C에서는 블록 주석을 이용해
/*/../usr/bin/env gcc "$0" "$@"; ./a.out; rm -vf a.out; exit; */같은 방식으로도 가능함Swift용 uv 같은 개념임
Swift는 shebang도 공식 지원함
#!을 직접 써도 됨예전 TCC 시절에 “C 스크립팅”으로 이런 방식을 썼음
큰 프로젝트에서는 빌드 스크립트가 매니페스트를 읽고 빌드 후 실행하는 구조였음
하지만 환경 제어가 어려워서 실무에는 부적합함
shebang을 직접 지원함
더 인체공학적인 언어를 원한다면 .NET 10의 “run file directly” 기능도 있음
shebang을 지원하고, 스크립트 내에서 패키지를 자동 설치함
#:sdk지시어로 웹앱도 바로 실행 가능함다만 AOT 컴파일은 아직 거칠음
처음엔 Python 비판일 줄 알았는데, 오히려 언어 생태계의 방향성을 생각하게 됨
ML이 Python에 묶인 건 큰 실수라고 봄
느리고, 타입 시스템이 불편하며, 배포가 어렵기 때문임
이제는 TypeScript, Go, Rust 같은 대안을 고려해야 함
다만 ML이 Python을 택한 이유는 C 기반 FFI 때문임
NodeJS나 Rust, Go는 FFI가 약함
Python은 여기서 강점을 가짐
이상적인 건 Python처럼 간단하지만 더 나은 타입 시스템과 배포 체계를 가진 언어임
JS 생태계에서 나온 언어로 Python을 대체하고 싶진 않음
Lisp이나 Lua(Torch)가 더 적합했지만, 단순함 때문에 Python이 선택됨
나도 Lisp 기반의 ML 프레임워크를 개발 중이지만, 채택은 어려울 것 같음
버전 호환성 문제, semver 부재, 불안정한 생태계 등으로 인해 JS보다 뒤처진 느낌임
JS/Node는 지난 10년간 성숙했지만 Python은 여전히 2012년에 머물러 있음
ML이 Python에 표준화된 건 정말 아쉬움
CLI 도구를 만들 때 Python보다 Go가 훨씬 빠름
LOC 차이 때문에 Python으로 돌아오긴 했지만, 실행할 때마다 Go가 그립음
아마 OCaml이 이상적이지만, 구식 툴링이 부담스러움
Go 스크립트의 문제는 첫 줄에 공백이 없어야 한다는 점임
gopls가 자동 포맷팅을 강제하기 때문임CI에서도 포맷 일관성을 유지해야 하므로, 이건 실무적으로 중요함
하지만 더 큰 문제는 go.mod를 쓸 수 없다는 것임
즉, 의존성 버전을 지정할 수 없어 호환성 보장이 약해짐