Nếu bạn từng gặp tình huống cài thư viện cho dự án này rồi dự án kia bị hỏng, hoặc chuyển code sang máy khác thì chạy không nổi, nguyên nhân gần như luôn là quản lý phụ thuộc. Môi trường ảo giải quyết vấn đề đó.
Vấn đề mà môi trường ảo giải quyết
Khi bạn chạy pip install, gói được cài vào Python hệ thống — dùng chung cho mọi dự án. Dự án A cần thư viện phiên bản 1.0, dự án B cần phiên bản 2.0. Cài cái này thì hỏng cái kia.
Môi trường ảo tạo ra một thư mục riêng chứa bản Python và các gói của riêng dự án đó. Mỗi dự án một môi trường, hoàn toàn độc lập.
venv — công cụ có sẵn
venv đi kèm Python từ phiên bản 3.3, không cần cài gì thêm:
python3 -m venv .venv
# Kích hoạt
source .venv/bin/activate # Linux, macOS
.venv\Scripts\activate # Windows
# Thoát
deactivate
Sau khi kích hoạt, dấu nhắc lệnh sẽ có tiền tố (.venv). Từ lúc này, python và pip trỏ vào môi trường ảo chứ không phải Python hệ thống.
which python # .../du_an/.venv/bin/python
pip install requests
pip list
Đặt tên thư mục là .venv đã trở thành quy ước — hầu hết trình soạn thảo tự nhận diện và kích hoạt giúp bạn.
Ghi lại danh sách phụ thuộc
pip freeze > requirements.txt
File này cho phép người khác tái tạo đúng môi trường của bạn:
pip install -r requirements.txt
Nhớ thêm .venv/ vào .gitignore. Đừng đưa thư mục môi trường ảo lên kho mã nguồn — nó nặng, phụ thuộc hệ điều hành, và tái tạo được từ requirements.txt.
Hạn chế của pip freeze
File sinh từ pip freeze trộn lẫn thứ bạn thực sự cần với các phụ thuộc gián tiếp. Sau vài tháng, bạn không còn biết gói nào là do mình cài, gói nào chỉ là phụ thuộc của gói khác.
Cách rõ ràng hơn là tự ghi những gì bạn trực tiếp cần vào requirements.in, rồi sinh file khóa từ đó bằng pip-tools:
pip install pip-tools
pip-compile requirements.in # sinh requirements.txt đầy đủ
pip-sync requirements.txt # đồng bộ môi trường đúng theo file
uv — nhanh hơn nhiều lần
uv là công cụ viết bằng Rust, làm được việc của pip, venv, pip-tools và cả pyenv. Điểm khác biệt lớn nhất là tốc độ: cài đặt một tập phụ thuộc lớn nhanh hơn pip đáng kể.
# Cài uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# Tạo dự án mới
uv init du-an-cua-toi
cd du-an-cua-toi
# Thêm thư viện
uv add requests pandas
uv add --dev pytest ruff
# Chạy code trong môi trường của dự án
uv run python main.py
uv run pytest
uv tự tạo và quản lý môi trường ảo, bạn không cần kích hoạt thủ công. Nó cũng sinh file uv.lock ghi chính xác phiên bản của mọi gói, đảm bảo môi trường tái tạo giống hệt trên mọi máy.
# Trên máy khác, tái tạo đúng môi trường
uv sync
uv còn quản lý được cả phiên bản Python:
uv python install 3.12
uv run --python 3.11 python main.py
Poetry
Poetry là lựa chọn phổ biến khác, đặc biệt khi bạn phát triển thư viện để phát hành:
poetry new du-an
poetry add requests
poetry install
poetry run python main.py
poetry build # đóng gói để phát hành lên PyPI
Poetry mạnh về khâu đóng gói và phát hành. Nếu bạn chỉ viết ứng dụng, uv thường gọn và nhanh hơn.
conda
conda có ưu thế riêng trong lĩnh vực khoa học dữ liệu vì nó quản lý được cả thư viện không phải Python — trình biên dịch C, thư viện đại số tuyến tính, CUDA:
conda create -n phan-tich python=3.12
conda activate phan-tich
conda install pandas scikit-learn jupyter
Nếu công việc của bạn cần các thư viện tính toán biên dịch sẵn, conda tiết kiệm rất nhiều thời gian. Ngược lại, với ứng dụng web thông thường thì nó là công cụ nặng nề không cần thiết.
Nên chọn cái nào?
- Mới học, muốn hiểu bản chất →
venv+pip - Dự án ứng dụng thông thường →
uv - Viết thư viện để phát hành → Poetry hoặc
uv - Khoa học dữ liệu, cần thư viện biên dịch → conda
Một số thói quen tốt
Tạo môi trường ảo ngay khi bắt đầu dự án, trước cả khi viết dòng code đầu tiên. Việc này mất mười giây và tiết kiệm cho bạn hàng giờ gỡ rối sau này.
Ghim phiên bản trong file khóa cho môi trường thật. Để requests không ghim phiên bản đồng nghĩa với việc một bản cập nhật có thay đổi không tương thích có thể làm hỏng hệ thống của bạn vào lúc bạn không ngờ nhất.
Đừng cài gói vào Python hệ thống. Trên Ubuntu và nhiều bản Linux hiện nay, việc này còn bị chặn hẳn — và đó là một thay đổi đúng đắn.