Python Virtual Environments (venv)
Keep each project's packages separate
In this lesson
A virtual environment (or venv) gives each Python project its own private set of packages, so different projects never clash when they need different versions. Creating one per project is a habit worth forming early — this lesson shows you how to make, activate, and leave a venv.
Explain it like I’m 5
A virtual environment is a separate toolbox for each project. Project A’s tools stay in A’s box and Project B’s in B’s, so upgrading one never breaks the other.
The problem it solves
Without isolation, every package installs into one shared global Python. Then Project A needs version 1 of a library while Project B needs version 2 — and they can’t both win. A virtual environment (‘venv’) gives each project its own isolated packages, so their requirements never conflict.
Creating a venv
From your project folder, run python3 -m venv .venv. This creates a .venv folder containing a private copy of Python and a place for that project’s packages. You make one venv per project; the .venv name is a common convention.
Activating it
Creating isn’t enough — you must activate it so your shell uses it. On macOS/Linux: source .venv/bin/activate. On Windows: .venv\Scripts\activate. Once active, your prompt usually shows (.venv), and pip install now installs into this project only.
# Run these in a terminal, in your project folder.
python3 -m venv .venv
source .venv/bin/activate
# your prompt now shows (.venv)
python -m pip install requests
deactivate
(.venv) $ # packages now install into this project only
Deactivating, and not committing it
Run deactivate to leave the environment and return to the global Python. Because a venv is large and machine-specific, you don’t share it — instead you record your packages in a requirements.txt file (next lesson) and add .venv/ to .gitignore so it’s never committed.
What’s inside a venv, and the tools around it
A venv isn’t magic — it’s just a folder. Inside .venv there’s a bin/ (or Scripts/ on Windows) holding a Python and a pip, and a lib/ where this project’s packages get installed. Activating simply puts that bin/ first on your PATH, so plain python and pip point at the project’s copies.
The built-in python -m venv is the standard tool. You may also hear of virtualenv (a faster third-party version) and conda (popular in data science) — all solve the same isolation problem. You record what’s installed with pip and a requirements.txt.
.venv/
bin/ # activate script, python, pip (Scripts/ on Windows)
lib/ # this project's installed packages
pyvenv.cfg # records which base Python it was built from
Common mistake: Installing packages without activating the venv
If you forget to activate, pip install goes to the global Python, defeating the isolation and risking version clashes.
Check for the (.venv) prefix in your prompt before installing. If it’s missing, activate the environment first.
Common mistake: Committing the .venv folder to version control
The folder is large and tied to your machine and OS, so it bloats the repo and won’t work for others.
Add .venv/ to .gitignore and share a requirements.txt so others can recreate the environment.
What problem does a virtual environment solve?
A venv gives each project its own packages, preventing version clashes between projects.
After creating a venv, what must you do before installing into it?
You must activate the venv in your terminal so that pip installs into it rather than the global Python.
Mini exercise (easy)
Write the exact terminal commands to: create a venv called .venv, activate it on macOS/Linux, and confirm which Python is now in use.
These are terminal commands you’d type in a real shell — we can’t run them in the browser, but you can assemble them here so the checker can confirm them. Fill in the three command strings.
create = "..." # create a venv called .venv
activate = "..." # activate it on macOS/Linux
confirm = "..." # confirm which python is now in use
print(create)
print(activate)
print(confirm)
The confirmation command is which python (it should point inside .venv).
create = "python -m venv .venv"
activate = "source .venv/bin/activate"
confirm = "which python"
print(create)
print(activate)
print(confirm)
assert create == "python -m venv .venv", "create a venv with: python -m venv .venv"
assert activate == "source .venv/bin/activate", "activate with: source .venv/bin/activate"
assert confirm == "which python", "confirm with: which python"
print("✓ Commands correct!")