본문 바로가기
Python Basic

파이썬 가상 환경 분리하고 패키지 의존성 관리하기

by mjk0618 2023. 11. 24.

개발 프로젝트를 팀 단위로 진행하다보면 사용하는 언어나 라이브러리 버전이 맞지 않아 문제가 생길 때가 종종 있습니다. 예를 들어 팀원 중 한 명이 작성한 코드가 상위 버전에서만 작동하는 기능이라 하위 버전의 라이브러리를 사용하는 다른 팀원은 실행할 수 없는 경우가 있습니다. 팀 프로젝트 뿐만 아니라 코드를 배포하는 단계에서도 버전 관리는 중요합니다. 개발 환경에서는 문제 없이 작동하는 코드가 배포된 환경에서는 버전 문제를 겪을 수도 있기 때문입니다.

 

이런 문제를 피하기 위해서 팀 프로젝트나 코드 배포에 익숙한 개발자들은 프로젝트마다 독립적인 환경을 구성하곤 합니다. 저도 기존에는 파이썬이나 라이브러리를 모두 컴퓨터에 글로벌하게 설치하여 별도의 가상환경 분리나 의존성 관리를 해주지 않았지만, 새롭게 프로젝트를 진행할 때는 이 부분을 조금 신경써려고 합니다. 그래서 프로젝트 착수에 앞서 몇 가지 공부한 내용을 정리해보았습니다.

 


 

가상 환경 분리

먼저 프로젝트 별로 가상 환경을 분리하는 방법을 설명하겠습니다. 사용할 라이브러리는 virtualenv입니다. 파이썬 3.4 이상의 버전부터는 내장 라이브러리인 venv를 사용할 수 있지만, 확장된 기능을 사용하는 virtualenv를 기준으로 설명하겠습니다. virtualenv는 자체적으로 파이썬 버전은 관리할 수 없습니다. 따라서 이 글에서는 주로 패키지 의존성 관리에 대해서 설명하며 윈도우 10, 파이썬 버전 3.10.2를 기준으로 설명하였습니다.

 

먼저 다음 명령어를 터미널에 입력하여 virtualenv를 설치해야 합니다.

 

pip install virtualenv

 

설치가 완료되면 다음 명령어를 통해 가상 환경을 하나 만듭니다. 일반적으로 튜토리얼에선 myenv라는 이름을 사용하지만, 가상 환경 이름은 임의로 설정하면 됩니다. 저는 env_test라고 하겠습니다.

 

virtualenv env_test

 

 

그러면 다음과 같은 내부 구조를 갖는 env_test라는 새로운 폴더가 생성됩니다.

 

 

Lib 폴더 안에는 파이썬 내장 모듈이 저장되고, 그 안에 site-packages 폴더에 pip install을 설치한 외부 라이브러리가 저장됩니다. Scripts 폴더에는 pip와 같이 실행할 수 있는 스크립트가 저장되어 있습니다. cfg 파일은 가상 환경에 대한 정보를 저장하고 있습니다.

 

그럼 이제 가상 환경을 실행해보겠습니다. 다음 명령어를 터미널에 입력합니다.

 

env_test/Scripts/activate

 

명령어를 실행하면 터미널의 명령줄 앞에 가상 환경의 이름이 표시됩니다. 가상 환경이 실행된 상태임을 의미합니다.

 

(env_test) PS C:\Users\Kang MinJae\Desktop\Code

 

이 상태에서 pip list를 실행하여 설치된 외부 라이브러리 목록을 보겠습니다.

 

(env_test) PS C:\Users\Kang MinJae\Desktop\Code> pip list
Package    Version
---------- -------
pip        23.3.1 
setuptools 68.2.2 
wheel      0.41.3

 

원래 제 컴퓨터에는 여러 서드파티 라이브러리가 설치되어 있었는데, 이 가상 환경에서는 완전히 분리된 것을 볼 수 있습니다. 이제 여기에서 pip install을 통해 프로젝트에 필요한 라이브러리만을 설치하면 됩니다.

 


 

의존성 저장 및 불러오기

보통 의존성을 관리할 때 requirements라는 파일에 필요한 라이브러리와 버전을 작성하고 이 파일을 공유합니다. virtualenv에서도 requirements.txt를 작성하거나 불러와서 의존성을 관리할 수 있는데, 방법을 알아보겠습니다.

 

requirements를 작성하기 위해서 numpypandas를 설치하겠습니다. 일단은 버전을 명시하지 않고 최신 버전을 설치하였습니다. Lib > site-packages에 새로운 파일이 추가되는 것을 볼 수 있습니다. pip list를 통해서도 설치된 라이브러리를 확인할 수 있습니다.

 

(env_test) PS C:\Users\Kang MinJae\Desktop\Code> pip install numpy pandas
(env_test) PS C:\Users\Kang MinJae\Desktop\Code> pip list
Package         Version
--------------- ------------
numpy           1.26.2
pandas          2.1.3
pip             23.3.1
python-dateutil 2.8.2
pytz            2023.3.post1
setuptools      68.2.2
six             1.16.0
tzdata          2023.3
wheel           0.41.3

 

두 라이브러리와 의존성이 있는 다른 라이브러리도 설치되었네요. 그러면 이 패키지 정보를 하나의 파일로 저장해보겠습니다.

 

터미널에 다음 명령어를 입력하면 requirements.txt라는 파일 안에 패키지 정보가 저장됩니다.

 

(env_test) PS C:\Users\Kang MinJae\Desktop\Code> pip freeze > requirements.txt

 

 

만약 이 파일을 공유받았을 때 모든 패키지를 한 번에 설치하려면, requirements.txt를 프로젝트 폴더에 위치시키고, 다음 명령어를 실행하면 됩니다.

 

pip install -r requirements.txt

 

마지막으로 실행한 가상 환경에서 벗어나려면 터미널에 deactivate를 입력하면 됩니다. 그러면 다음과 같이 명령줄 앞에 (env_test)라는 문구가 사라지면서 가상 환경 실행이 종료됩니다.

 

deactivate

PS C:\Users\Kang MinJae\Desktop\Code>

 


 

Poetry를 사용한 패키지 관리

최근에는 Poetry라는 새로운 툴을 사용하여 패키지를 관리하는 방법도 많이 사용되고 있습니다. 아까 virtualenv에서 requirements를 생성할 때는 직접 설치하지 않은 다른 라이브러리도 같이 저장되는 문제가 있었습니다. 실제로 설치한 건 numpy와 pandas 뿐인데, pandas와 의존성이 있는 다른 라이브러리도 모두 표시되었죠. poetry는 이런 의존성을 다 분리해서 관리할 수 있게 해줍니다.

 

예를 들어서 아래는 poetry로 프로젝트를 초기화할 때 생성되는 파일인데, 직접 설치한 패키지에 대한 정보만을 따로 저장하고 있습니다.

 

 

그리고 pip list를 통해 실제 설치된 패키지를 확인해보면, 직접 설치한 패키지와 의존성이 있어 추가로 설치된 다른 패키지도 나타납니다. 이처럼 의존성을 조금 더 유연하게 분리할 수 있다는 장점이 있는데, 이 외에도 poetry만의 여러 강점이 있는 걸로 알고 있습니다.

 

(env-test-py3.10) PS C:\Users\Kang MinJae\Desktop\Code\env_test> pip list
Package         Version
--------------- ------------
numpy           1.26.2
pandas          2.1.3
pip             23.3.1
python-dateutil 2.8.2
pytz            2023.3.post1
setuptools      68.2.2
six             1.16.0
tzdata          2023.3

 

Poetry에 사용법이나 여러 기능들은 아직 잘 몰라서 일단은 이런 게 있다는 느낌으로 소개만 하고 설치법만 알려드리겠습니다. Poetry 공식 홈페이지나 다른 튜토리얼을 보면 설치하는 방법이 복잡하고 다양한데 저는 그냥 pip로 설치하였습니다. 현재는 별다른 충돌이 발생하지 않지만 추후 버그가 발견될 경우 수정하겠습니다.

 

pip install poetry

 

설치 후에 poetry init이라는 명령어를 실행하면, 터미널에서 프로젝트에 관한 몇 가지 설정을 할 수 있는데 직접 지정할 게 있으면 하고 아니면 그냥 엔터를 입력하면 건너뛸 수 있습니다. 프로젝트 초기 설정이 완료되면 poetry add 명령어를 사용하여 interactive하게 패키지를 하나씩 추가할 수 있습니다.

 

PS C:\Users\Kang MinJae\Desktop\Code> poetry init

This command will guide you through creating your pyproject.toml config.

Package name [code]: 
PS C:\Users\Kang MinJae\Desktop\Code> ^C
PS C:\Users\Kang MinJae\Desktop\Code> cd env_test
PS C:\Users\Kang MinJae\Desktop\Code\env_test> poetry init

This command will guide you through creating your pyproject.toml config.

Package name [env_test]: 
Version [0.1.0]:  
Description []:  
Author [MinJae Kang <kminjae618@gmail.com>, n to skip]:  
License []:  
Compatible Python versions [^3.10]:  

Would you like to define your main dependencies interactively? (yes/no) [yes]
You can specify a package in the following forms:
  - A single name (requests): this will search for matches on PyPI
  - A name and a constraint (requests@^2.23.0)
  - A git url (git+https://github.com/python-poetry/poetry.git)
  - A git url with a revision (git+https://github.com/python-poetry/poetry.git#develop)
  - A file path (../my-package/my-package.whl)
  - A directory (../my-package/)
  - A url (https://example.com/packages/my-package-0.1.0.tar.gz)

Package to add or search for (leave blank to skip): numpy
Found 20 packages matching numpy
Showing the first 10 matches

Enter package # to add, or the complete package name if it is not listed []:
 [ 0] numpy
 [ 1] numpy1
 [ 2] numpy-serializer
 [ 3] mapchete-numpy
 [ 4] hypothesis-numpy2
 [ 5] mlphys-numpy
 [ 6] video2numpy
 [ 7] numpy-io
 [ 8] topas2numpy
 [ 9] numpy-onlinestats
 > 0
Enter the version constraint to require (or leave blank to use the latest version):
Using version ^1.26.2 for numpy

Add a package (leave blank to skip): 

Would you like to define your development dependencies interactively? (yes/no) [yes]

Generated file

[tool.poetry]
version = "0.1.0"
description = ""
authors = ["MinJae Kang <kminjae618@gmail.com>"]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.10"
numpy = "^1.26.2"

[build-system]
requires = ["poetry-core"]

 

모든 설정을 마치고 poetry shell, poetry install 명령어를 통해 앞에서 지정한 패키지를 모두 설치하여 의존성을 관리할 수 있습니다. 이 글에서는 poetry에 대한 자세한 사용법을 다루지 않으니 구체적인 내용은 공식 문서를 참고해주세요.

 


 

이상으로 파이썬 가상 환경을 분리하고 라이브러리 버전을 관리하는 법을 간단하게 알아보았습니다. 앞서 말했듯이 팀 프로젝트, 또는 배포 환경을 고려하면 버전을 분리하고 의존성을 관리하는 것은 생각보다 중요한 문제입니다. 이 글에서 다룬 내용은 정말 기초적인 내용이지만, 이런 작업이 익숙해지면 라이브러리 뿐만 아니라 파이썬이나 운영체제와 같은 환경들도 모두 관리하여 도커 이미지로 배포한다고 알고 있습니다. 특히 딥러닝 모델 개발에서는 코드 재현을 위해서 개발 환경을 통합하는 게 정말 중요하기 때문에 이런 부분에 대해서도 공부하고 정리해봐야 할 것 같습니다.

'Python Basic' 카테고리의 다른 글

파이썬의 dis 모듈  (0) 2023.10.16
파이썬의 코딩 컨벤션과 PEP8 가이드  (1) 2023.09.27
print 문은 어떻게 동작할까?  (0) 2023.03.19

댓글