[Python] Python 버전 관리
프로젝트를 하면서 어떤 것들을 설치하거나 실행할 때, 많은 부분의 오류가 버전 관리에서 발생한다. 따라서 버전 관리에 대해 알아둔 상태에서 프로젝트를 진행하면 매우 효율적이다. 특히 현업에서는 제한된 환경에서 프로젝트를 할 때가 많고, pip
로 라이브러리를 설치할 때 꼬이는 경우도 많다. 어떻게 해야 버전을 잘 관리할 수 있을까?
버전관리
- 버전과 버저닝
- 버전 : 소프트웨어 제품의 특정 릴리스에 대한 고유한 식별자다. 즉, 소프트웨어가 처음 출시되었을 때나 업데이트가 이루어질 때마다 새로운 버전 번호를 부여한다.
- 버저닝 : 소프트웨어의 유니크한 버전 이름, 버전 번호를 할당하는 과정이다. 즉 버전을 정의하는 방법이자, 다양한 버전을 관리하고 식별하기 위해 사용되는 방법이다.
버저닝 방법
- CalVer(Calendar Versioning)
Ubuntu 20.04
와 같은 경우에 해당한다.- 날짜 시간 시스템을 사용해서 버전 번호를 할당하는 방법이다. 대표적으로 연도와 월로 구성된다.
-
이해하기 쉬우며, 날짜 기반으로 출시 시기를 예측하기 수월하고 유연하게 접근이 가능하다.
- SemVer(Semantic Versioning)
Python 3.11.0
와 같은 경우에 해당한다.- 마침표로 구분된 주번호, 부번호, 패치번호로 구성되어 있다.
- 이전 버전과 호환되지 않는 변경이 있는 경우 주번호가 증가한다.
- 이전 버전과 호환되며 새로운 기능이 추가되면 부번호 증가한다.
-
이전 버전에서 버그 수정이 진행되면 패치번호가 증가한다.
- HashVer(Hash Versioning)
Git commit 7e6d3fd
과 같은 경우에 해당한다.SHA-1
,SHA-256
등의 해시 알고리즘을 사용하여 버전에 대해 고유 식별자를 생성한다.- 코드가 변경될 때마다 해시가 변경되므로 모든 버전이 고유한 식별자를 가지도록 보장한다. 일반적으로 Github 와 같이 코드를 관리할 때 많이 사용한다.
- 버저닝의 핵심은, 어떤 버저닝 방법을 사용하는 것과 상관없이 코드의 특정 상태를 적당히 표현하는 것이 핵심이다.
- 버전이 왜 필요할까?
- 버전이 없으면 특정 상태에 대한 통일된 명칭이 없어서 서로 커뮤니케이션이 어렵다.
- PM 과 프로젝트 로드맵 계획 회의를 할 때, 릴리스에 대한 통일된 관점이 필요하다.
- 사용자에게 앱스토어에서 릴리스 내용을 공지할 때도 필요하다.
- 즉 사람들과 커뮤니케이션을 하는 상황이라면 버전을 사용해서 커뮤니케이션을 수월하게 할 수 있다.
- 버전은 항상 필요할 수 있고 아닐 수도 있다. 한번 릴리스하고 끝이면 굳이 필요 없다. 그러나 유지보수, 지속적 개발을 할 때는 버전이 필요하다.
Python 버전관리
- Python 은 SemVer 를 사용해서 버저닝을 한다. ex.
3.11.2
,3.8.1
,…
- 많이 사용하는
3.11.x
버전은 그보다 아래의 마이너 버전에서 호환된다. 따라서3.8.x
에서 생성한 코드는 그대로3.11.x
에서 실행해도 문제가 없다. - 단, 패키지나 라이브러리가
3.11.x
을 지원하지 않을 수도 있는데, 이는 다른 문제다. - 그러나 Python
3.x.x
버전은 아래 메이저 버전인2.x.x
와 호환되지 않는다. 특정 함수가 다르기도 하다. - 프로젝트에 Python 버전을 표현하는 방법은 일반적으로 Github
README.md
에 작성하게 된다. 이 때 작성 방법은 아래와 같다.- Python 3.8 이상에서 실행 가능 :
python >= 3.8
,python 3.8+
,python 3.8^
- Python 3.8 로만 실행 가능 :
python == 3.8
- Python 3.10 이상, 3.11 미만 버전에서 실행 가능 :
python = ">=3.10,<3.11"
- Python 3.8 이상에서 실행 가능 :
Python 설치
- Python 의 설치 방법은 매우 다양하다. 공식 홈페이지,
conda
,docker
,brew
,apt
,winget
,pyenv
등 설치방법이 너무 많다. 어떤 방식이 현업에서 표준으로 활용될까? - 너무 많은 방법을 쓰면 충돌이 날 가능성이 존재한다. 예를 들어
conda
와pyenv
를 같이 설치하여 사용하면,pyenv
에서 설치한 python 은 무시되고conda
에서 사용하는 python 만 호출된다. - 만약
pyenv
에서 설치한 python 을 실행시키려면python 3.11
과 같이 명시적으로 표현해줘야 한다. - 따라서 python 설치 전 지금 사용하는 python 이 어디서 설치된 것인지 확인하는 과정이 필요하다. 이는
which
명령어를 통해which python
으로 어떤 파일을 실행시키는 것인지 확인할 수 있다.which
명령어는 Linux CLI 환경에서 사용자가 실행 가능한 바이너리 파일의 위치가 어디에 있는지를 알 수 있는 명령어다. 이 때 여러 방법으로 설치하면 저장된 곳이 달라서 혼란이 있다.
- python 버전이 꼬이면 추후에 하나의 방법으로 통일하는 번거로운 과정이 필요하게 된다.
-
아래는 python 설치 방법을 비교한 표다.
- 일반적으로 배포할 때
conda
는 잘 안쓴다. 통계 라이브러리가 기본으로 깔려 있어서 무겁기 때문이다. - Mac OS 나 Linux 는 사용하는 shell 설정파일(
~/.bashrc
,~/.zshrc
) 끝에 환경 변수들을 추가해야 한다.- shell 은 사용자가 문자를 입력해 컴퓨터에 명령할 수 있도록 하는 프로그램이다.
export PATH=”~/.pyenv/bin:$PATH”
eval”$(pyenv init 1)”
eval”$(pyenv virtualenv-init -)”
- 내가 어떤 shell 을 쓰는지 확인하는 법은
echo $SHELL
을 CLI 에서 실행시켜보면 된다. - 환경변수 추가 후
source “shell 설정 파일"
로 shell 설정을 업데이트 한다(ex.source ~/.zshrc
). 이렇게 되면 환경변수에 저장된다. - 또한
pyenv
에서pyenv shell 3.11.0
와 같이 현재 shell 에 특정 파이썬 버전을 활성화할 수 있다. - global 을 쓰면
pyenv global 3.11.0
와 같이 기본 python 버전을 설정 가능함.
Python 프로젝트 버전 관리(가상환경)
- Python 을 사용하는 프로젝트의 버전 관리에 대해 알아보자. 일반적으로 가상환경을 가장 많이 사용한다.
-
가상환경이란 프로젝트 별로 각자의 환경을 갖게 하여 격리된 버전을 가질 수 있게 해준다.
-
가상환경을 만들면 별도의 프로젝트 패키지가 생겨서 별도로 관리할 수 있다.
- 프로젝트 별 가상환경은 Python 버전, 설치한 패키지 목록을 다르게 가져갈 수 있고 관리할 수 있다.
- 이러한 가상환경도 다양한 방법으로 생성할 수 있다.
venv
,conda
,pyenv-virtualenv
,pipenv
등이 있다.venv
는 python 가상환경 구축에 가장 많이 사용되고 내장된 기능이다.python -m venv .venv
- 프로젝트 최상위 경로에서
.venv
로 만드는 것이 관습이다. - 가상환경에 접속하기 위해서는
source .venv/bin/activate
명령어를 사용한다. - 접속하고 나면 shell 왼쪽에
(.venv)
와 같은 가상환경 접속이 표시된다.
venv
의 구조- bin
- shell 에서 명령어 입력 시, 이 경로 내에서 제일 먼저 찾는다.
- python 입력 시 어떤 python 을 실행시키는 지 알수 있다.
- lib
- 패키지 설치 시, 이 경로에 설치하게 된다.
.py
에서 import 시 이 경로에서 제일 먼저 찾는다.
- 패키지 설치 시, 이 경로에 설치하게 된다.
- bin
패키지 매니저
- 패키지를 설치하고 버전을 관리하는데 편리한 tool 이 패키지 매니저다. python 패키지 매니저는 여러가지가 있다.
pip
,poetry
,conda
(conda 는 python 이라기 보다 anaconda 자체의 패키지 매니저)
pip
는 python 의 내장 패키지 매니저다. 따라서 가장 많이 사용한다.pip
로 하나의 패키지만 설치했는데 그와 관련된 의존성 패키지가 같이 설치되는 경우가 많다.- 설치된 패키지 목록을 출력할 때
pip list
를 사용하게 되는데, 만약 의존성 패키지 제외하고 싶을 때는pip list —not-required —format=freeze
를 사용하면 꼭 필요한 패키지만 보여준다. - 또한 일반적으로
pip freeze > requirements.txt
명령어를 통해 설치한 패키지 목록을 저장한다. 이렇게 저장한 패키지 목록을pip install -r requirements.txt
로 다른 환경에서 그대로 설치 가능하다. - python 내장 pip 보다는 최신 버전 pip 를 사용하는 것이 좋다. 따라서
pip install —upgrade pip
명령어를 통해pip
를 업데이트 하자. - 간혹 패키지 설치가 잘 안될 때 최신 버전의 pip 를 설치하면 잘 설치되는 경우가 있다. 버전 업이 될수록 버그가 픽스된다거나 속도가 향상되는 업데이트들이 진행되기 때문에, 항상 최신 버전으로 업데이트 후 사용하기를 권장한다.
pip
는 쉽게 사용할 수 있으나 문제점이 존재한다. 개발 환경과 배포 환경의 패키지가 분리되지 않는다는 점이다.- 개발하는 과정에서만 사용되고 실제 배포 환경에서는 사용되지 않는 패키지(ex. Formatter 인
Black
)도 실제 배포할 때requirements.txt
에 포함되어 설치되고 디스크 용량을 더 사용하게 될 수 있다. - 따라서 배포 환경이 아닌, 개발 환경에서만 사용하는 패키지들이 있을 때 이 두 패키지 목록을 분리해야 한다. 가상환경을 통한 격리처럼 개발과 배포 환경도 분리할 필요성이 존재한다는 것이다.
pip list
로는 패키지간의 의존성을 알 수 없다.pip uninstall
할 때 의존성이 있던 패키지들(간접적으로 설치된)은 삭제되지 않는다. 따라서 사용하지 않는 패키지들이 그대로 남아있게 된다.
- 즉
pip
로는 정교하게 패키지 관리를 할 수 없다. 혼자 개발할 때는 크게 중요하지 않을 수 있지만, 협업하며 개발해야 할 때는 중요할 수 있다.
Poetry
- 이러한
pip
의 문제점을 개선하기 위해 나온 패키지 매니저가 바로 poetry 다. - 공식문서에 따라 Mac OS, Linux 의 경우 아래와 같이 설치할 수 있다.
curl -sSL https://install.python-poetry.org | python3 -
- 이후 shell 설정 파일에서 환경 변수를 추가한다.
export PATH=$PATH:$HOME/.poetry/bin
- poetry 로 만들어지는
pyproject.toml
은 poetry 에서만 쓰이는 것은 아니고 python 프로젝트에 대한 메타 정보를 담고 있는 파일이다. python 프로젝트에 대한 버저닝을 이 파일 내에서 명시할 수 있다. -
또한
pip install
이 아니라poetry add 명령어
로 패키지를 설치한다. 만약 뒤에-D
옵션을 붙이면 개발 환경에서만 사용할 패키지를 설치할 수 있다. ex.poetry add black -D
poetry show —tree
를 입력하면 직접 설치한 패키지, 간접적으로 설치된 패키지를 따로 보여주어 의존성도 명확히 볼 수 있다.pyproject.toml
에는 개발 환경에 설치된 패키지와 그렇지 않은 것을 구분하여 볼 수 있다.dev
가 개발 환경에서만 사용되는 패키지다.
댓글 남기기