Python Virtual Environments
Learn how to isolate project dependencies with Python virtual environments for reliable, reproducible development.
Why Virtual Environments Matter
A virtual environment is a self-contained Python runtime that includes its own interpreter, libraries, and scripts. It keeps project dependencies isolated so that upgrades or changes in one project do not break another.
- Maintain different dependency versions per project.
- Package applications with predictable requirements.
- Collaborate confidently with teammates using shared requirements files.
Prerequisites
Virtual environments ship with modern Python distributions. Verify that you have Python 3.6 or later installed and that pip works:
python --version
pip --versionIf you manage multiple Python versions, prefer calling the interpreter explicitly (for example, python3.11).
Create a Virtual Environment
Use python -m venv to create a virtual environment in your project directory. Choose a descriptive folder name like .venv or env.
Windows
py -3 -m venv .venvmacOS / Linux
python3 -m venv .venvThe command creates a folder containing the interpreter binary, the standard library, and helper scripts.
Activate the Environment
Activation updates your shell so that python and pip resolve inside the virtual environment.
Windows (PowerShell)
.venv\Scripts\Activate.ps1Windows (Command Prompt)
.venv\Scripts\activate.batmacOS / Linux
source .venv/bin/activateActivated environments typically display the folder name in your prompt: (.venv) user@machine project %.
Install Dependencies
With the environment active, use pip to install packages. These packages are stored inside .venv and will not affect system Python.
pip install requests numpyConfirm what is installed at any time:
pip listDeactivate When Finished
Exit the environment with the deactivate command. Your shell reverts to the global Python context.
deactivateShare Dependencies
Create a requirements.txt file so collaborators can recreate the environment quickly.
Freeze installed versions
pip freeze > requirements.txtRecreate the environment elsewhere
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtKeep requirements.txt under version control so that deployments match development.
Upgrade Virtual Environment Tools
Upgrade pip and wheel within the environment to access the latest packaging features.
pip install --upgrade pip setuptools wheelTo recreate the environment from scratch, delete .venv and run the creation and installation commands again.
Working With Multiple Python Versions
Pair virtual environments with tools like pyenv or the Windows Launcher (py -3.11) to target a specific interpreter version.
py -3.11 -m venv .venv
.venv\Scripts\Activate.ps1
python --version # 3.11.xThis approach ensures compatibility testing across releases without polluting the base system.
Best Practices
- Add the virtual environment folder (for example,
.venv/) to your.gitignore. - Name environments per project or per purpose (
.venv,.venv-tests). - Keep requirements updated but pinned to prevent unexpected upgrades.
- Automate activation with IDE settings or shell aliases.
Troubleshooting Tips
If activation fails on Windows PowerShell, unblock scripts by setting the execution policy for the current user:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUserWhen pip installs wheel files built for the wrong platform, recreate the environment with the correct Python version or architecture.
Next Steps
You now have an isolated workspace with predictable dependencies. Continue with the File Handling lessons to learn how to interact with files using Python.
Why Virtual Environments?
A virtual environment is an isolated Python installation for one project. It keeps each project's dependencies (and versions) separate, so upgrading a package for project A never breaks project B.
Rule of thumb: one virtual environment per project. Never install project packages into your global system Python.
Create, Activate, Deactivate
# 1. create (folder named .venv)
python -m venv .venv
# 2. activate
# Windows: .venv\Scripts\activate
# macOS/Linux: source .venv/bin/activate
# 3. your prompt now shows (.venv) - install freely
pip install requests
# 4. leave the environment
deactivate| OS | Activate command |
|---|---|
| Windows (PowerShell) | .venv\Scripts\Activate.ps1 |
| Windows (cmd) | .venv\Scripts\activate.bat |
| macOS / Linux | source .venv/bin/activate |
Try It Yourself
Exercise 1: Create and activate a virtual environment called .venv, then confirm it is active.
Show solution
python -m venv .venv
source .venv/bin/activate # (or .venv\Scripts\activate on Windows)
which python # points inside .venvExercise 2: Inside the environment, install rich and freeze the requirements.
Show solution
pip install rich
pip freeze > requirements.txtKey Takeaways
- Isolate each project with its own
venv. - Create with
python -m venv .venv, then activate it. - Add
.venv/to.gitignore; commitrequirements.txtinstead.
📘 Real-World Deep Dive
A virtualenv isolates a project's dependencies so <code>system</code> and <code>user</code> packages can't interfere. It's the first line of defence against the "works on my machine" bug.
Real-Life Scenario
Bootstrap a project from a fresh checkout: create the venv, check the interpreter version, and install dev tools in one go.
Real-Life Example
import subprocess, sys, venv, shutil
from pathlib import Path
ROOT = Path.cwd()
VENV = ROOT / ".venv"
def run(*args: str) -> None:
print("$ " + " ".join(args))
subprocess.run(args, check=True)
if VENV.exists():
print(f"removing existing {VENV}")
shutil.rmtree(VENV)
builder = venv.EnvBuilder(with_pip=True)
builder.create(VENV)
print(f"created {VENV}")
py = VENV / ("Scripts" if sys.platform == "win32" else "bin") / ("python.exe" if sys.platform == "win32" else "python")
run(str(py), "-m", "pip", "install", "--upgrade", "pip", "wheel", "setuptools")
run(str(py), "-m", "pip", "install", "-r", "requirements.txt")
run(str(py), "-c", "import sys; print('interpreter:', sys.version.split()[0])")Expected Output
$ python -m venv .venv
created ...\.venv
$ .venv/bin/python -m pip install --upgrade pip wheel setuptools
$ .venv/bin/python -m pip install -r requirements.txt
interpreter: 3.12.4Common mistakes
- Committing
.venvblows up the repo and surprises IDEs — always gitignore it. - Different shells have different activation commands: bash uses
source, fish uses., PowerShell uses&. - A venv on the system drive slows down cross-filesystem moves on macOS — consider
virtualenvfor fast relocation.
🚀 Performance & Best Practices
uv venv+uv pip syncis many times faster thanpython -m venv+pip install -r.- Pre-compile bytecode after install:
python -m compileall .venv/lib. - Use
--system-site-packagesonly when you trust the system; otherwise keep them isolated.
🧪 Try It Yourself
- Write
Makefiletargetsvenvandinstallthat perform both steps. - Compare install time of
uv syncvs.pip installon a 100-package lockfile. - Add a pytest that asserts
sys.prefix != sys.base_prefixbefore running anything.