Skip to content

Virtual Environments Nền tảng

Virtual Environment = Sandbox cho Python = Mỗi project một thế giới riêng

Learning Outcomes

Sau khi hoàn thành trang này, bạn sẽ:

  • ✅ Hiểu tại sao cần virtual environments và cách chúng hoạt động
  • ✅ So sánh venv vs virtualenv vs conda và biết khi nào dùng cái nào
  • ✅ Thiết lập isolation strategies cho các loại project khác nhau
  • ✅ So sánh Poetry vs pip-tools vs uv và chọn tool phù hợp
  • ✅ Tránh các lỗi phổ biến khi quản lý environments

Tại sao cần Virtual Environments?

The Dependency Hell Problem

python
# Project A cần:
# requests==2.25.0
# numpy==1.19.0

# Project B cần:
# requests==2.28.0  # ❌ Conflict!
# numpy==1.24.0     # ❌ Conflict!

# Không có virtual environment:
# - Cài requests 2.28.0 → Project A broken
# - Cài requests 2.25.0 → Project B broken
# - Cài cả hai? Không thể!

Virtual Environment = Isolation

System Python (/usr/bin/python3)
├── site-packages/  ← Shared by ALL projects (dangerous!)
│   ├── requests==2.25.0
│   └── numpy==1.19.0

Project A (venv_a/)
├── bin/python3     ← Isolated Python
└── lib/site-packages/
    ├── requests==2.25.0  ✅ Project A's version
    └── numpy==1.19.0

Project B (venv_b/)
├── bin/python3     ← Isolated Python
└── lib/site-packages/
    ├── requests==2.28.0  ✅ Project B's version
    └── numpy==1.24.0

venv vs virtualenv vs conda

So sánh tổng quan

Featurevenvvirtualenvconda
Built-in✅ Python 3.3+❌ Cần cài❌ Cần cài
SpeedTrung bìnhNhanhChậm
Python versionsChỉ version hiện tạiNhiều versionsNhiều versions
Non-Python deps✅ (C libs, CUDA)
SizeNhỏNhỏLớn
Use caseGeneral PythonGeneral PythonData Science, ML

1. venv (Built-in) - Khuyến nghị cho hầu hết projects

bash
# Tạo virtual environment
python -m venv .venv

# Activate (Linux/macOS)
source .venv/bin/activate

# Activate (Windows CMD)
.venv\Scripts\activate.bat

# Activate (Windows PowerShell)
.venv\Scripts\Activate.ps1

# Deactivate
deactivate

# Xóa environment (chỉ cần xóa folder)
rm -rf .venv
python
# Kiểm tra đang dùng venv nào
import sys
print(sys.prefix)      # /path/to/project/.venv
print(sys.executable)  # /path/to/project/.venv/bin/python

2. virtualenv - Nhanh hơn, nhiều features hơn

bash
# Cài đặt
pip install virtualenv

# Tạo environment (nhanh hơn venv nhờ caching)
virtualenv .venv

# Tạo với Python version cụ thể
virtualenv -p python3.11 .venv

# Tạo với system site-packages (kế thừa packages từ system)
virtualenv --system-site-packages .venv

Khi nào dùng virtualenv thay vì venv?

  • Cần tạo nhiều environments (virtualenv cache nhanh hơn)
  • Cần Python version khác với system Python
  • Cần --system-site-packages option

3. conda - Cho Data Science & ML

bash
# Cài đặt Miniconda (lightweight) hoặc Anaconda (full)
# https://docs.conda.io/en/latest/miniconda.html

# Tạo environment
conda create -n myproject python=3.12

# Activate
conda activate myproject

# Cài packages (từ conda-forge channel)
conda install numpy pandas scikit-learn

# Cài packages từ pip (khi conda không có)
pip install some-package

# Export environment
conda env export > environment.yml

# Recreate từ file
conda env create -f environment.yml

# Deactivate
conda deactivate

# Xóa environment
conda env remove -n myproject

Khi nào dùng conda?

  • ✅ Data Science, Machine Learning projects
  • ✅ Cần CUDA, cuDNN cho GPU computing
  • ✅ Cần C libraries (OpenCV, GDAL, etc.)
  • ✅ Team đã dùng conda
  • ❌ Web development (overkill)
  • ❌ Cần lightweight solution

Isolation Strategies

Strategy 1: Per-Project venv (Khuyến nghị)

my-project/
├── .venv/              # ← Virtual environment
├── src/
│   └── my_package/
├── tests/
├── pyproject.toml
└── .gitignore          # ← Ignore .venv/
ini
# .gitignore
.venv/
venv/
env/
.env/

Ưu điểm:

  • Isolation hoàn toàn
  • Dễ reproduce
  • Không conflict giữa projects

Nhược điểm:

  • Tốn disk space (mỗi project ~50-200MB)

Strategy 2: Centralized venvs

~/.virtualenvs/
├── project-a/
├── project-b/
└── project-c/

# Hoặc dùng virtualenvwrapper
pip install virtualenvwrapper

# Thêm vào ~/.bashrc hoặc ~/.zshrc
export WORKON_HOME=$HOME/.virtualenvs
source /usr/local/bin/virtualenvwrapper.sh

# Commands
mkvirtualenv project-a
workon project-a
deactivate
rmvirtualenv project-a

Ưu điểm:

  • Quản lý tập trung
  • Dễ switch giữa projects

Nhược điểm:

  • Khó track environment nào cho project nào
  • Không portable

Strategy 3: Docker-based Isolation

dockerfile
# Dockerfile
FROM python:3.12-slim

WORKDIR /app

# Copy requirements first (cache layer)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy source code
COPY . .

CMD ["python", "-m", "myapp"]
yaml
# docker-compose.yml
services:
  app:
    build: .
    volumes:
      - .:/app
    environment:
      - PYTHONDONTWRITEBYTECODE=1
      - PYTHONUNBUFFERED=1

Ưu điểm:

  • Isolation hoàn toàn (OS level)
  • Reproducible across machines
  • Production-ready

Nhược điểm:

  • Overhead (Docker daemon)
  • Slower development cycle
  • Learning curve

Poetry vs pip-tools vs uv

So sánh tổng quan

Featurepip + requirements.txtpip-toolsPoetryuv
Lock file❌ Manual✅ requirements.txt✅ poetry.lock✅ uv.lock
Dependency resolutionBasicGoodExcellentExcellent
SpeedSlowMediumSlow🚀 Very Fast
Virtual env management
Build & publish
pyproject.toml
Learning curveLowLowMediumLow

1. pip + requirements.txt (Legacy)

bash
# Cài packages
pip install requests numpy

# Freeze dependencies
pip freeze > requirements.txt

# Install từ file
pip install -r requirements.txt
txt
# requirements.txt
requests==2.31.0
numpy==1.26.0
certifi==2023.7.22  # ← Transitive dependency (không cần thiết)
charset-normalizer==3.3.0
idna==3.4
urllib3==2.0.7

Vấn đề:

  • pip freeze bao gồm cả transitive dependencies
  • Không phân biệt dev vs production dependencies
  • Không có lock file (version có thể thay đổi)
bash
# Cài đặt
pip install pip-tools

# Tạo requirements.in (chỉ direct dependencies)
echo "requests" > requirements.in
echo "numpy" >> requirements.in

# Compile thành requirements.txt (với pinned versions)
pip-compile requirements.in

# Upgrade all packages
pip-compile --upgrade requirements.in

# Sync environment với requirements.txt
pip-sync requirements.txt
txt
# requirements.in (bạn viết)
requests
numpy

# requirements.txt (pip-compile generate)
# This file is autogenerated by pip-compile
certifi==2023.7.22
    # via requests
charset-normalizer==3.3.0
    # via requests
idna==3.4
    # via requests
numpy==1.26.0
    # via -r requirements.in
requests==2.31.0
    # via -r requirements.in
urllib3==2.0.7
    # via requests

Ưu điểm:

  • Simple, dễ hiểu
  • Tương thích với pip ecosystem
  • Reproducible builds
bash
# Cài đặt
curl -sSL https://install.python-poetry.org | python3 -

# Tạo project mới
poetry new my-project

# Hoặc init trong project có sẵn
poetry init

# Thêm dependency
poetry add requests
poetry add pytest --group dev

# Install dependencies
poetry install

# Run trong virtual environment
poetry run python main.py

# Activate shell
poetry shell

# Build package
poetry build

# Publish to PyPI
poetry publish
toml
# pyproject.toml
[tool.poetry]
name = "my-project"
version = "0.1.0"
description = "My awesome project"
authors = ["Your Name <you@example.com>"]

[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.31.0"

[tool.poetry.group.dev.dependencies]
pytest = "^7.4.0"
black = "^23.0.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Ưu điểm:

  • All-in-one solution
  • Excellent dependency resolution
  • Built-in virtual environment management
  • Easy publishing

Nhược điểm:

  • Slower than pip
  • Learning curve
  • Sometimes conflicts với pip ecosystem

4. uv (Modern, Fast) 🚀

bash
# Cài đặt
curl -LsSf https://astral.sh/uv/install.sh | sh

# Hoặc với pip
pip install uv

# Tạo virtual environment (10-100x faster than venv)
uv venv

# Cài packages (10-100x faster than pip)
uv pip install requests numpy

# Compile requirements
uv pip compile requirements.in -o requirements.txt

# Sync environment
uv pip sync requirements.txt

# Init project với pyproject.toml
uv init

# Add dependency
uv add requests
uv add pytest --dev

# Run script
uv run python main.py

# Lock dependencies
uv lock

# Sync từ lock file
uv sync

Ưu điểm:

  • 🚀 Extremely fast (written in Rust)
  • Drop-in replacement cho pip
  • Modern pyproject.toml support
  • Active development by Astral (creators of Ruff)

Nhược điểm:

  • Relatively new (2024)
  • Some edge cases chưa handle

Workflow Recommendations

Cho Beginners / Small Projects

bash
# Dùng venv + pip-tools
python -m venv .venv
source .venv/bin/activate
pip install pip-tools

# requirements.in
echo "requests" > requirements.in
pip-compile requirements.in
pip-sync requirements.txt

Cho Production Projects

bash
# Dùng Poetry hoặc uv
poetry new my-project
cd my-project
poetry add fastapi uvicorn
poetry add pytest black --group dev
poetry install

Cho Data Science

bash
# Dùng conda
conda create -n ml-project python=3.12
conda activate ml-project
conda install numpy pandas scikit-learn jupyter
conda install pytorch torchvision -c pytorch

Cho Maximum Speed

bash
# Dùng uv
uv venv
source .venv/bin/activate
uv pip install requests numpy pandas

Production Pitfalls ⚠️

1. Không commit lock file

bash
# ❌ BAD: Chỉ commit requirements.in
git add requirements.in
git commit -m "Add dependencies"

# ✅ GOOD: Commit cả lock file
git add requirements.in requirements.txt
git commit -m "Add dependencies with locked versions"

# Hoặc với Poetry
git add pyproject.toml poetry.lock

Tại sao? Không có lock file → mỗi lần install có thể get different versions → "Works on my machine" syndrome.

2. Dùng pip freeze trực tiếp

bash
# ❌ BAD: Freeze tất cả (bao gồm dev tools)
pip freeze > requirements.txt
# Output bao gồm: black, pytest, mypy... (không cần trong production)

# ✅ GOOD: Dùng pip-tools hoặc Poetry
pip-compile requirements.in  # Chỉ production deps
poetry export -f requirements.txt --without-hashes  # Export từ Poetry

3. Không pin Python version

toml
# ❌ BAD: Không specify Python version
[tool.poetry.dependencies]
requests = "^2.31.0"

# ✅ GOOD: Pin Python version
[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.31.0"

4. Activate sai environment

bash
# ❌ BAD: Quên activate
cd my-project
pip install requests  # Cài vào system Python!

# ✅ GOOD: Luôn activate trước
cd my-project
source .venv/bin/activate
pip install requests

# ✅ BETTER: Dùng Poetry/uv (auto-manage venv)
poetry add requests
uv add requests

5. Không gitignore virtual environment

ini
# ❌ BAD: Commit .venv vào git
# (Không có .gitignore entry)

# ✅ GOOD: Ignore virtual environment
.venv/
venv/
env/
.env/
__pycache__/
*.pyc

6. Mixing package managers

bash
# ❌ BAD: Dùng cả pip và conda
conda install numpy
pip install pandas  # Có thể conflict!

# ✅ GOOD: Stick với một tool
# Nếu dùng conda, dùng conda cho tất cả
conda install numpy pandas scikit-learn

# Chỉ dùng pip khi package không có trên conda
pip install some-rare-package

Quick Reference

bash
# === VENV (Built-in) ===
python -m venv .venv
source .venv/bin/activate  # Linux/macOS
.venv\Scripts\activate     # Windows
deactivate

# === VIRTUALENV ===
pip install virtualenv
virtualenv .venv
virtualenv -p python3.11 .venv

# === CONDA ===
conda create -n myenv python=3.12
conda activate myenv
conda install package
conda deactivate

# === PIP-TOOLS ===
pip install pip-tools
pip-compile requirements.in
pip-sync requirements.txt

# === POETRY ===
poetry new project
poetry add package
poetry add package --group dev
poetry install
poetry run python script.py

# === UV ===
uv venv
uv pip install package
uv add package
uv run python script.py