Don't install packages globally. Use virtual environments.

Why Virtual Environments?

Without them:

  • Projects share dependencies
  • Version conflicts break things
  • "Works on my machine" problems
  • Upgrading one project breaks another

With them:

  • Each project has its own packages
  • No conflicts between projects
  • Reproducible environments
  • Clean uninstall

Creating a Virtual Environment

# Create
python -m venv venv
 
# Activate (macOS/Linux)
source venv/bin/activate
 
# Activate (Windows)
venv\Scripts\activate
 
# Deactivate
deactivate

The venv folder contains a copy of Python and all installed packages.

Project Structure

myproject/
├── venv/           # Don't commit this
├── src/
├── tests/
├── requirements.txt
├── pyproject.toml
└── .gitignore

Add to .gitignore:

venv/
.venv/
env/

Installing Packages

# Activate first
source venv/bin/activate
 
# Install packages
pip install requests
pip install flask pandas numpy
 
# Check what's installed
pip list

requirements.txt

Save dependencies:

pip freeze > requirements.txt

Install from file:

pip install -r requirements.txt

Example requirements.txt:

requests==2.31.0
flask==3.0.0
pandas==2.1.0

Better: Pin Versions

Unpinned dependencies cause problems:

# Bad - versions can change
requests
flask

# Good - exact versions
requests==2.31.0
flask==3.0.0

Even better, use ranges:

requests>=2.31.0,<3.0.0
flask>=3.0.0,<4.0.0

Dev Dependencies

Separate production and development:

# requirements.txt (production)
requests==2.31.0
flask==3.0.0

# requirements-dev.txt
-r requirements.txt
pytest==7.4.0
black==23.7.0
mypy==1.5.0

Install dev dependencies:

pip install -r requirements-dev.txt

Using pyproject.toml

Modern approach:

[project]
name = "myproject"
version = "0.1.0"
dependencies = [
    "requests>=2.31.0",
    "flask>=3.0.0",
]
 
[project.optional-dependencies]
dev = [
    "pytest>=7.4.0",
    "black>=23.7.0",
]

Install:

pip install -e .           # Production
pip install -e ".[dev]"    # With dev dependencies

pip-tools for Better Management

pip install pip-tools

Create requirements.in:

requests
flask

Compile with pinned versions:

pip-compile requirements.in

Generates requirements.txt with exact versions and hashes.

Update dependencies:

pip-compile --upgrade requirements.in

Common Issues

Wrong Python Version

# Check which Python
which python
python --version
 
# Create with specific version
python3.11 -m venv venv

Packages Not Found

Did you activate the environment?

source venv/bin/activate
which pip  # Should show venv path

Environment Corruption

Delete and recreate:

rm -rf venv
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Alternatives

virtualenv

More features than venv:

pip install virtualenv
virtualenv venv

conda

For data science with non-Python dependencies:

conda create -n myenv python=3.11
conda activate myenv
conda install numpy pandas

Poetry

All-in-one dependency management:

poetry new myproject
poetry add requests
poetry install

PDM

PEP-compliant modern tool:

pdm init
pdm add requests
pdm install

My Workflow

# New project
mkdir myproject && cd myproject
python -m venv venv
source venv/bin/activate
 
# Install packages
pip install requests flask
 
# Save dependencies
pip freeze > requirements.txt
 
# Later / on another machine
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Simple, reliable, works everywhere.

Quick Reference

CommandPurpose
python -m venv venvCreate environment
source venv/bin/activateActivate (Unix)
venv\Scripts\activateActivate (Windows)
deactivateDeactivate
pip install XInstall package
pip freeze > requirements.txtSave dependencies
pip install -r requirements.txtInstall from file

Virtual environments are essential. Use them for every project.

React to this post: