본문 바로가기

시행착오 노트

나의 파이썬 환경 구축기 1 - 써본 것들에 대한 생각

언젠간 한 번쯤은 나의 파이썬 개발 환경에 대해 글을 쓰려했었다.
anaconda, virtualenv, pyenv 등등 지금까지 이것저것 다 써본 뒤... 이제 때가 왔다.
이번 글에서 내 맥북에 내가 어떻게 파이썬 개발 환경을 만들었는지 차례대로 적어볼 것이다.

다음과 같은 분들에게 이 글이 흥미가 있지 않을까 싶다.

  • 주로 파이썬으로 개발하는 개발자 (분석가 아니다.)
  • 파이썬 버전에 민감하게 반응하시는 분 (특히 새로운 파이썬 버전을 적극적으로 사용하려고 허시는 분)
  • 깔끔하고 트렌디하게 파이썬 개발 환경 구축하고 싶은 분

거두절미하고, 이 글의 결론은 다음과 같다.

파이썬 버전 관리는 pyenv로,
가상 환경, 패키지 설치 및 관리는 poetry로 하자.

아, 난 맥을 쓰므로 맥을 쓴다는 것을 전제로 적겠다.


1. 파이썬 설치에 대하여

먼저 파이썬 설치에 대하여 말해보려 한다.
가장 쉽게는 다음처럼 brew 로 python 설치하는 것이다.

$ brew install python3

혹은 공식 홈페이지에서 파일을 다운받아 설치할 수도 있다.

하지만, 나는 파이썬 버전을 좀 더 신경 써서 설치하고 싶었다.
brew install 명령어를 보면 파이썬 버전이 전혀 명시되어 있지 않다.
아는 사람들은 알겠지만, 파이썬 3에도 많은 마이너 버전들이 있다. 그리고 마이너 버전 간에도 꽤 큰 변화들이 많다.
예를 들어, 최근에 릴리즈 된 python 3.9 에는 IANA timezone을 지원하는 zoneinfo 패키지가 내부 모듈로 추가됐다! (datetime.timezone 을 쓰거나 pytz 같은 외부 라이브러리 쓰던 사람들은 얼른 파이썬 3.9를 써보고 싶을 것이다!)

파이썬의 다양한 버전을 CLI를 통해 좀 더 쉽게 다운받을 수 있게 해주는 프로그램이 있는데 그게 바로 pyenv다.
pyenv를 사용하면 다음처럼 파이썬을 다운받아 쓸 수 있다.

$ pyenv install 3.9.0

매우 쉽다!
다음과 같이 다양한 버전의 파이썬을 여러 개 설치할 수 있다.

$ pyenv install -l
...
3.6.10
3.6.11
3.6.12
3.7.0
3.7-dev
3.7.1
3.7.2
... (생략)

아무튼 설치하는 방법과 구체적으로 세팅하는 방법은 아래서 다루겠다.
여기서의 요지는, pyenv로 손쉽게 파이썬의 다양한 버전을 다운받고 사용할 수 있다는 것이다.


2. 가상 환경에 대하여

파이썬 가상 환경의 필요성은 따로 말하지는 않겠다.
내가 지금까지 알거나 써봤던 파이썬 가상환경 만드는 방법들은 다음과 같다.

  • conda
    • anaconda 설치 후, conda라는 별도의 가상 환경을 만들 수 있다.
    • conda에는 pandas, numpy 같은 데이터 사이언스에 필요한 여러 패키지들이 같이 설치된다.
    • 분석가 입장에서 처음 파이썬과 쥬피터 노트북 쓸 때 좋긴 하다. 나도 처음에 이거 썼다.
    • 하지만 conda에 불필요한 패키지들이 여럿 깔리며, 이게 꽤 헤비 하다.
    • 특히 나 같은 개발자들은 내가 모르는 뭔가가 깔리면 굉장히 마음이 불편하다. 따라서 비추.
  • virtualenv
    • 파이썬 가상 환경 하면 가장 만만하게 등장하는 녀석 아닐까 싶다. 그만큼 쉽고 자주 보인다.
    • conda에 비하면 불필요한 패키지를 안 깔아주므로 가볍고 명확해서 개발자에게 좀 더 좋다.
    • 다만, 가상 한경에서 어떤 파이썬 버전을 쓸 것인가 명시해주는 게 매우 꼴 보기 싫음.
    • 예를 들면 이런 식이다. $ virtualenv --python=/usr/bin/python3.7
    • 안정적이긴 하나 그만큼 오래된 방식이다. 최근에 더 좋은 다른 방법들이 많이 나왔다.
  • pipenv
    • 사실 써볼까 이리저리 살펴봤으나, 써보진 않았다.
    • 예전에 꾸준히 개발되었다가... 중단되었다가.. 다시 최근에 개발하며 배포하는 거 같다.
    • 비슷한 느낌의 poetry와 고민하다가 난 결국 poetry로 갔다.
  • pyenv-virutalenv
    • 위에서 설명한 pyenv의 플러그인 격으로, 사용하려면 pyenv가 설치되어 있어야 한다.
    • pyenv로 설치한 파이썬 버전으로 가상 환경을 만들 수 있다.
    • 예를 들면 이런 식이다. $ pyenv virtualenv 3.9.0 my-virtual-env
    • virutalenv를 쓰면 가상 환경 정보를 담고있는 .venv/ 가 파이썬 패키지 내부에 생기는데, pyenv-virutalenv는 패키지 외부에 별도로 만들어 저장한다. 이게 어떻게 보면 장점이자 단점이다.
    • 나는 여러 파이썬 프로젝트를 다루어, 가상 환경을 자주 스위칭하게 되는데, 이때 가상 환경 정보는 프로젝트 내부에 있는게 좋은거 같아서 pyenv-virutalenv를 잘 안쓰게 되었다.

나는 conda -> virtualenv -> pyenv-virtualenv 순으로 사용해왔다.
그러다 지금은 최종적으로 poetry를 쓴다.
사실 poetry는 가상환경 툴은 아니고 패키지 매니전데, 이 안에 virtualenv도 사용하기 때문에... poetry를 쓰면 굳이 가상 환경에 대해 따로 신경 쓰지 않아도 된다. 자세한 내용은 아래에서.


3. 패키지 매니저에 대해서

패키지 매니저가 뭐냐. 잘 모르겠으면 그냥 pip 를 떠올리면 된다.
pip 사용법은 아주 단순하다. 뭐 설치하고 싶으면 pip install 하면 끝이다.
그리고 설치한 패키지를 보고 싶으면 pip list 하거나 pip freeze > requirements.txt 하면 된다.

허나 pip의 가장 큰 문제는... pip listpip freeze패키지 의존성이 전혀 보이지 않는다는 것이다.
예를 들어 다음 상황을 보자.

# 현재 가상환경에 아무것도 깔려있지 않음
$ pip list
Package    Version
---------- -------
pip        20.2.3
setuptools 49.2.1

# flask 설치
$ pip install flask
...

# pip list로 설치된 패키지들을 다시 조회 해보면...
$ pip list
Package      Version
------------ -------
click        7.1.2
Flask        1.1.2
itsdangerous 1.1.0
Jinja2       2.11.2
MarkupSafe   1.1.1
pip          20.2.3
setuptools   49.2.1
Werkzeug     1.0.1

위에서 보다시피, 나는 flask 라는 패키지 하나만 설치했을 뿐인데, Jinja2 , MarkupSafe 등... 내가 설치하지 않은 패키지들도 같이 설치된다. 사실 이런 패키지들은 flask 라는 패키지를 설치하면 같이 설치되는 녀석들, 즉 flask 가 의존하고 있는 패키지들인데, 문제는 이렇게 의존성 구분 없이 표현된다는 것이다. 나중에 이걸 본 사람은 실제로 어떤 패키지가 중심이 되는지 전혀 모르게 된다.

또, 자바스크립트를 써 본 사람들은 npm 이라는 패키지 매니저를 사용해봤을 텐데, npmnpm install -D 와 같은 옵션을 제공하여 개발 환경에만 패키지를 설치할 수 있다. 그런데 pip 에는 이런 기능이 없다.

여하튼... 이런 배경에서 탄생하게 된 게 pipenvpoetry 다. 여기서 나는 poetry 를 사용하고 있다.
poetry를 사용하면 pip install 이 아니라 다음처럼 poetry add 로 패키지를 추가한다.

$ poetry add flask

이 과정 중에 virutalenv 를 이용하여 가상 환경도 생성한다. (.venv/ 디렉토리가 생긴다.)
여하튼 이렇게 flask 를 설치하고 난 뒤, 다음처럼 설치된 패키지 목록을 볼 수 있다.

$ poetry show --tree
flask 1.1.2 A simple framework for building complex web applications.
├── click >=5.1
├── itsdangerous >=0.24
├── jinja2 >=2.10.1
│   └── markupsafe >=0.23
└── werkzeug >=0.15

확실히.. pip 보다 훨씬 진보된 게 느껴질 거라고 생각한다.


 

원래 이 글에 pyenv + poetry 설치와 다루는 법을 다루려 했는데... 생각보다 글이 길어졌다.
글을 나누어... 다음 글에는 이 부분을 자세히 다뤄보겠다.