正在加载,请稍候…

Python Virtual Environments: venv, conda, and pyenv Explained

Master Python environment management with venv, pip, conda, and pyenv. Learn how to create isolated environments, manage dependencies, and avoid version conflicts.

Why Python Virtual Environments Matter

Python packages are installed globally by default. This causes version conflicts when different projects need different package versions:

Project A: requires Django 4.2
Project B: requires Django 3.2

# Without virtual environments: you can only have one version installed
# The newer install overwrites the older one, breaking one of your projects

Virtual environments create isolated Python installations with their own packages — each project gets its own library versions without interfering with others.

venv — Python's Built-in Tool

# Create a virtual environment
python3 -m venv myenv

# Activate (Linux/macOS)
source myenv/bin/activate

# Activate (Windows)
myenv\Scripts\activate.bat    # CMD
myenv\Scripts\Activate.ps1   # PowerShell

# You'll see (myenv) prefix in your shell prompt
(myenv) $ pip install requests

# Deactivate
deactivate

What happens when you activate?

which python   # before: /usr/bin/python3
source myenv/bin/activate
which python   # after: /path/to/myenv/bin/python

Activation adds the environment's bin/ directory to the front of PATH, so python and pip commands use the environment's copies.

Managing packages

# Install packages
pip install requests
pip install "django>=4.2,<5.0"  # version constraints
pip install requests==2.31.0    # exact version

# Install from requirements file
pip install -r requirements.txt

# List installed packages
pip list
pip freeze  # exact versions, suitable for requirements.txt

# Generate requirements.txt
pip freeze > requirements.txt

# Check for outdated packages
pip list --outdated

# Upgrade a package
pip install --upgrade requests

# Uninstall
pip uninstall requests

requirements.txt best practices

# requirements.txt — include version constraints, not exact pins
# for application libraries you control
requests>=2.28.0,<3.0.0
django>=4.2.0,<5.0.0
celery[redis]>=5.3.0

# requirements-dev.txt — tools you don't ship
pytest>=7.0.0
black>=23.0.0
mypy>=1.0.0

For production deployments where you want reproducibility:

# Generate a pinned lockfile
pip freeze > requirements-lock.txt

# The lockfile pins exact versions of all transitive dependencies
# Use this for deployment, not the loose requirements.txt

pyenv — Managing Multiple Python Versions

venv manages packages; pyenv manages Python versions themselves.

# Install pyenv (macOS)
brew install pyenv

# Install pyenv (Linux)
curl https://pyenv.run | bash

# List available Python versions
pyenv install --list | grep "3\.12"

# Install a specific version
pyenv install 3.12.3
pyenv install 3.11.8

# List installed versions
pyenv versions

# Set global default
pyenv global 3.12.3

# Set local version for a project (creates .python-version file)
cd myproject
pyenv local 3.11.8
python --version  # 3.11.8 (overrides global)

# Set version for current shell session
pyenv shell 3.10.14

pyenv + venv workflow

# 1. Go to project
cd myproject

# 2. Set Python version
pyenv local 3.12.3

# 3. Create virtual environment with that Python
python -m venv .venv

# 4. Activate
source .venv/bin/activate

# 5. Install dependencies
pip install -r requirements.txt

Add to .gitignore

# .gitignore
.venv/
venv/
env/
__pycache__/
*.pyc
.python-version  # commit this if you want to enforce Python version for team

pip-tools — Better Dependency Management

pip-tools separates abstract requirements from pinned lockfiles:

pip install pip-tools

# requirements.in — your direct dependencies (abstract)
cat > requirements.in << EOF
requests>=2.28.0
django>=4.2.0
EOF

# Compile to pinned lockfile (includes all transitive deps)
pip-compile requirements.in -o requirements.txt

# Install from lockfile
pip-sync requirements.txt

# Update all packages to latest compatible versions
pip-compile --upgrade requirements.in

This gives you the best of both worlds: readable direct dependencies in .in files, reproducible full lockfile in .txt.

conda — Scientific Computing and Data Science

conda is popular in data science because it manages non-Python dependencies too (C libraries, CUDA, etc.).

# Create environment
conda create -n myenv python=3.12

# Activate
conda activate myenv

# Install packages
conda install numpy pandas matplotlib
conda install -c conda-forge scikit-learn  # from community channel

# Install with pip inside conda env (for packages not in conda channels)
pip install some-package

# Export environment
conda env export > environment.yml

# Create environment from file
conda env create -f environment.yml

# List environments
conda env list

# Remove environment
conda env remove -n myenv

environment.yml

name: data-analysis
channels:
  - conda-forge
  - defaults
dependencies:
  - python=3.12
  - numpy>=1.24
  - pandas>=2.0
  - matplotlib>=3.7
  - pip:
    - custom-package>=1.0.0  # packages only on PyPI

Poetry — Modern Dependency Management

Poetry combines environment management, dependency resolution, and packaging in one tool.

# Install Poetry
curl -sSL https://install.python-poetry.org | python3 -

# Create new project
poetry new myproject
cd myproject

# Add dependencies
poetry add requests
poetry add "django>=4.2,<5.0"
poetry add --dev pytest black mypy  # dev dependencies

# Install dependencies (creates .venv automatically)
poetry install

# Run in environment
poetry run python script.py
poetry run pytest

# Activate shell
poetry shell

# Update dependencies
poetry update

# Show dependency tree
poetry show --tree

pyproject.toml (Poetry)

[tool.poetry]
name = "myproject"
version = "1.0.0"

[tool.poetry.dependencies]
python = "^3.12"
requests = "^2.28.0"
django = ">=4.2,<5.0"

[tool.poetry.dev-dependencies]
pytest = "^7.0"
black = "^23.0"
mypy = "^1.0"

Poetry generates a poetry.lock file — a complete lockfile you commit to version control for reproducible installs.

uv — The Modern Fast Alternative

uv (from Astral) is a new Rust-based Python package manager that's 10-100x faster than pip:

# Install uv
pip install uv
# or: curl -LsSf https://astral.sh/uv/install.sh | sh

# Create virtual environment
uv venv

# Install packages (much faster than pip)
uv pip install requests django

# Install from requirements.txt
uv pip install -r requirements.txt

# Use pyproject.toml workflow
uv add requests  # adds to pyproject.toml and installs
uv sync          # install all deps from lock file

Choosing the Right Tool

Tool Best For
venv + pip Simple projects, maximum compatibility
pyenv + venv Multiple Python versions, any project type
pip-tools Teams needing reproducible builds without heavy tooling
Poetry Modern workflow, packaging and publishing packages
conda Data science, scientific computing, non-Python dependencies
uv Speed-critical workflows, modern projects (rapidly maturing)

Common Problems and Fixes

# "command not found: python" after activation
which python3   # use python3 instead
python3 -m venv .venv

# Packages installed but can't import
# Check you're in the right environment
which python    # should point to .venv/bin/python

# pip installs to wrong location
# Never use sudo with pip in a virtual environment
# If you accidentally did: rm -rf the venv and start fresh

# requirements.txt not reproducible across platforms
# Use pip-tools or Poetry which generate cross-platform lockfiles

→ Explore Python configuration files and JSON data with the JSON Viewer.