Python 가상환경 — venv와 의존성 관리
이 토픽을 마치면
가상환경이 왜 필요한지 이해하고, venv로 프로젝트별 독립 환경을 만들 수 있으며, requirements.txt로 의존성을 관리하는 방법을 익힙니다.
왜 가상환경이 필요한가
Python에서 pip install requests를 하면, 패키지가 시스템 전역에 설치됩니다. 두 프로젝트가 같은 패키지의 다른 버전을 필요로 하면 문제가 됩니다.
Project A: requests==2.28.0 필요
Project B: requests==2.31.0 필요
시스템: requests는 하나만 설치 가능 → 충돌!가상환경은 프로젝트마다 독립된 Python 환경을 만듭니다. 각 프로젝트가 자신만의 패키지 세트를 가지므로 충돌이 없습니다.
Project A/venv: requests==2.28.0 (독립)
Project B/venv: requests==2.31.0 (독립)
시스템 Python: 영향 없음venv 생성과 활성화
# 가상환경 생성python3 -m venv venv
# 활성화 (macOS/Linux)source venv/bin/activate
# 활성화 (Windows)venv\Scripts\activate
# 프롬프트가 변경됨(venv) $ python --versionPython 3.11.5python3 -m venv venv에서 두 번째 venv는 폴더 이름입니다. 관례적으로 venv 또는 .venv를 사용합니다.
활성화 확인
# 어떤 Python을 쓰고 있는가?(venv) $ which python/home/user/project/venv/bin/python
# 비활성화(venv) $ deactivate$ which python/usr/bin/python3활성화하면 python과 pip가 가상환경 내부의 것을 가리킵니다. 비활성화하면 시스템 Python으로 돌아갑니다.
가상환경 안에서 패키지 설치
(venv) $ pip install requests flask
(venv) $ pip listPackage Version---------- -------Flask 3.0.0requests 2.31.0...이 패키지들은 venv/lib/ 폴더 안에 설치됩니다. 시스템 Python에는 영향을 주지 않습니다.
requirements.txt — 의존성 기록
# 현재 설치된 패키지를 기록(venv) $ pip freeze > requirements.txt# requirements.txt
Flask==3.0.0
Jinja2==3.1.2
MarkupSafe==2.1.3
Werkzeug==3.0.1
click==8.1.7
requests==2.31.0
urllib3==2.1.0
certifi==2023.11.17
charset-normalizer==3.3.2
idna==3.6pip freeze는 설치된 모든 패키지와 정확한 버전을 출력합니다. 이것을 requirements.txt에 저장하면, 다른 사람(또는 서버)이 같은 환경을 재현할 수 있습니다.
의존성 설치
# 다른 환경에서 동일한 패키지 설치(venv) $ pip install -r requirements.txt직접 작성 vs pip freeze
# 직접 작성 (최소한)
Flask>=3.0
requests>=2.31
# pip freeze (전체)
Flask==3.0.0
Jinja2==3.1.2
... (의존성까지 모두)pip freeze는 하위 의존성까지 전부 포함합니다. 직접 작성하면 핵심 패키지만 명시하고 버전 범위를 쓸 수 있어서 유연합니다. 프로젝트 규모에 따라 선택합니다.
.gitignore — venv를 커밋하지 않는다
# .gitignore
venv/
.venv/
__pycache__/
*.pyc가상환경 폴더는 절대 git에 포함하지 않습니다. 이유:
- 크기: venv 폴더는 수십~수백 MB
- OS 종속: macOS에서 만든 venv는 Linux에서 작동하지 않음
- 재현 가능:
requirements.txt가 있으면 언제든 재생성 가능
# 새로운 환경에서 프로젝트 시작git clone projectcd projectpython3 -m venv venvsource venv/bin/activatepip install -r requirements.txt실전 워크플로
# 1. 프로젝트 시작mkdir my-project && cd my-projectpython3 -m venv venvsource venv/bin/activate
# 2. 패키지 설치pip install flask requests pandas
# 3. 개발...
# 4. 의존성 저장pip freeze > requirements.txt
# 5. git commitgit add .git commit -m "Add requirements"
# 6. 다른 사람이 받아서 실행git clone <repo>cd my-projectpython3 -m venv venvsource venv/bin/activatepip install -r requirements.txtpython app.py여러 Python 버전 다루기
# 시스템에 Python 3.10과 3.12가 모두 설치된 경우python3.10 -m venv venv310python3.12 -m venv venv312
# 각 venv는 생성 시 사용한 Python 버전에 묶임source venv310/bin/activatepython --version # Python 3.10.x
source venv312/bin/activatepython --version # Python 3.12.xvenv는 생성 시점의 Python 버전을 사용합니다. 프로젝트마다 다른 Python 버전이 필요하면 해당 버전으로 venv를 생성합니다.
venv vs conda
| venv | conda | |
|---|---|---|
| 설치 | Python 기본 내장 | 별도 설치 (Anaconda/Miniconda) |
| 범위 | Python 패키지만 관리 | Python + C 라이브러리 + 시스템 패키지 |
| Python 버전 | 시스템에 설치된 버전만 사용 | Python 자체 버전도 관리 |
| 패키지 소스 | PyPI (pip) | conda-forge + PyPI |
| 용량 | 가벼움 (수 MB) | 무거움 (수 GB) |
| 추천 대상 | 웹 개발, 일반 Python | 데이터 과학, ML (NumPy/SciPy 의존성 복잡) |
# conda 환경 생성 (비교 참고)conda create -n myenv python=3.11conda activate myenvconda install numpy pandas scikit-learn데이터 과학에서 conda가 선호되는 이유는 NumPy, SciPy 같은 패키지가 C/Fortran 라이브러리에 의존하기 때문입니다. conda는 이런 바이너리 의존성까지 관리합니다. 하지만 웹 개발이나 일반 Python 프로젝트에서는 venv로 충분합니다.
현대적 의존성 관리 — pyproject.toml
Python 3.11+ 프로젝트에서는 requirements.txt 대신 pyproject.toml을 사용하는 추세입니다.
# pyproject.toml
[project]
name = "my-project"
version = "1.0.0"
requires-python = ">=3.10"
dependencies = [
"flask>=3.0",
"requests>=2.31",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0",
"black>=23.0",
]# pyproject.toml 기반 설치pip install . # 프로덕션 의존성pip install ".[dev]" # 개발 의존성 포함requirements.txt는 단순 목록이고, pyproject.toml은 프로젝트 메타데이터(이름, 버전, Python 버전 제한)까지 포함합니다. 라이브러리를 배포할 계획이 있다면 pyproject.toml이 표준입니다.
자주 하는 실수
| 실수 | 결과 | 해결 |
|---|---|---|
| venv 미활성화 상태에서 pip install | 시스템 전역에 설치됨 | which pip으로 확인 후 설치 |
| venv 폴더를 git에 커밋 | 레포 크기 폭증 | .gitignore에 venv/ 추가 |
| requirements.txt 미갱신 | 다른 환경에서 패키지 누락 | 패키지 추가/삭제 후 pip freeze 재실행 |
| 시스템 Python에 직접 설치 | 프로젝트 간 충돌 | 항상 venv 안에서 작업 |
python vs python3 혼동 | 다른 버전의 Python 실행 | venv 활성화 후 python으로 통일 |
핵심 정리
| 명령 | 역할 |
|---|---|
python3 -m venv venv | 가상환경 생성 |
source venv/bin/activate | 활성화 |
deactivate | 비활성화 |
pip freeze > requirements.txt | 의존성 기록 |
pip install -r requirements.txt | 의존성 설치 |
가상환경은 "프로젝트마다 독립된 Python"입니다. 한 번 습관이 되면 패키지 충돌, "내 컴퓨터에서는 되는데" 문제, 배포 환경 불일치가 사라집니다. 새 프로젝트를 시작할 때 python3 -m venv venv를 첫 번째 명령으로 치는 것이 Python 개발의 기본입니다.