Overview
Virtual environments isolate a project's dependencies from the system Python and from other projects. They prevent version conflicts, keep global packages clean, and make deployments reproducible. This tutorial covers venv, pip, and the workflow used in real projects.
Why Virtual Environments Matter
Without isolation, installing a package for Project A can break Project B. For example, if Project A requires Django 4.2 and Project B requires Django 5.0, a single global installation cannot satisfy both.
| Approach | Isolation | Reproducibility |
|---|---|---|
| Global install | None | Poor — depends on host state |
venv | Per-project | Good with requirements.txt |
| Poetry / uv | Per-project | Excellent with lock files |
| Docker | Per-container | Best — full environment captured |
Python Version Check
python3 --version
venv is included in the standard library from Python 3.3 onward. If your distribution splits it into a separate package, install it:
# Ubuntu / Debian
sudo apt install python3-venv
Creating a Virtual Environment
mkdir my-project
cd my-project
python3 -m venv .venv
The convention is to name it .venv and add it to .gitignore.
Activating the Environment
| Platform | Command |
|---|---|
| Linux / macOS (bash, zsh) | source .venv/bin/activate |
| Windows (PowerShell) | .venv\Scripts\Activate.ps1 |
| Windows (cmd) | .venv\Scripts\activate.bat |
| Fish shell | source .venv/bin/activate.fish |
Once activated, your prompt shows the environment name. Verify with:
which python
which pip
Both should point inside .venv.
Installing Packages
pip install requests
pip install "flask==3.0.0"
pip list
pip show requests
Freezing Dependencies
pip freeze > requirements.txt
The file looks like this:
blinker==1.8.2
click==8.1.7
flask==3.0.0
itsdangerous==2.2.0
jinja2==3.1.4
werkzeug==3.0.3
Reproducing the Environment
On another machine or after cloning the repo:
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Upgrading and Removing Packages
pip install --upgrade requests
pip uninstall requests
pip install --upgrade pip
Deactivating
deactivate
To delete the environment completely, remove the directory:
rm -rf .venv
Recommended .gitignore Entries
.venv/
__pycache__/
*.pyc
.env
Beyond venv: Poetry and uv
For projects with complex dependency graphs, modern tools provide better resolution and lock files:
| Tool | Strength |
|---|---|
venv + pip | Built in, zero dependencies |
| Poetry | Lock file, dependency groups, publishing |
| uv | Extremely fast resolver and installer |
| pip-tools | Pinned requirements.txt from .in sources |
Common Problems
| Symptom | Cause | Fix |
|---|---|---|
pip: command not found | Environment not activated | Run the activation command for your platform |
| Packages installed globally by mistake | Forgot to activate before pip install | Check which pip; reinstall inside the venv |
| PowerShell blocks activation | Execution policy | Set-ExecutionPolicy -Scope CurrentUser RemoteSigned |
| Wrong Python version in venv | Created with the wrong interpreter | Delete .venv and recreate with python3.12 -m venv .venv |
