Virtual environments, and why they matter
This lesson explains the ModuleNotFoundError from module 6 — the one where you
definitely installed the package and Python insists it is not there — and the
python3-venv line from the installation lesson.
It is also the single habit that separates people whose projects keep working from people whose projects mysteriously stop.
The problem
Install a package without a virtual environment and it goes into your system Python, shared by everything.
Now imagine two projects:
- Project A, finished last year, uses Django 4.2
- Project B, starting today, needs Django 5.1
Install Django 5.1 and project A breaks, because there is one Django and both projects share it. Your options become upgrading project A — work you did not plan and may not be able to test — or not starting project B.
It gets worse with indirect dependencies. Package X needs requests 2.28;
package Y needs 2.31. Installing Y silently upgrades requests and breaks X,
with an error that mentions neither.
And it is not reproducible. "Works on my machine" usually means your machine has forty packages installed over two years, and a colleague's does not.
The solution
A virtual environment is a private folder holding its own Python and its own packages. Each project gets one. Installing into one cannot affect another.
Creating and using one
cd my-project
python -m venv .venv
That creates a .venv folder. python -m venv rather than a venv command —
the -m form runs the module belonging to the Python you invoked, which
guarantees the environment is built from the interpreter you meant.
On Ubuntu this is where you need the python3-venv package from the
installation lesson. If it errors, that is the fix.
Then activate it:
source .venv/bin/activate
On Windows PowerShell:
.venv\Scripts\Activate.ps1
Your prompt changes to show the environment name:
(.venv) priya@laptop:~/my-project$
That prefix is how you know it is active. No prefix, no environment — and
pip install then goes somewhere global.
To leave:
deactivate
Checking which Python you are on
The diagnostic worth memorising, from module 2:
python -c "import sys; print(sys.executable)"
Active, it prints something inside .venv. Inactive, it prints your system
Python. When a package is "not found" despite being installed, run this first —
it answers the question immediately.
pip list shows what is installed in the current environment. A freshly created
one has almost nothing, which is the point.
The ModuleNotFoundError from module 6
Now it makes sense. The usual sequence:
- You install a package in one terminal
- You run your code in another, or in an editor, where the environment is not active
ModuleNotFoundError, despite the package being installed — just not in the Python that is running
Two habits prevent it:
Install with python -m pip rather than bare pip.
python -m pip install requests
That installs into the Python you just invoked, whatever pip alone might
have resolved to. It removes an entire class of confusion.
Tell your editor which interpreter to use. In VS Code, the command palette,
Python: Select Interpreter, and pick the one in .venv. The version appears
in the bottom-right corner — the thing the setup lesson told you to check when
something makes no sense.
Always exclude it from Git
# .gitignore
.venv/
__pycache__/
*.pyc
A virtual environment is large, platform-specific, and completely reproducible
from requirements.txt. Committing one is a mistake — it bloats the repository
and does not work on anyone else's machine anyway.
Commit the list of dependencies, never the dependencies themselves. That is the next lesson.
Conventions
Name it .venv. The leading dot hides it, most tools look for it
automatically, and editors detect it without configuration. venv and env
also appear in the wild.
One per project, inside the project folder. Not shared, not somewhere central.
Recreate rather than repair. If an environment gets into a confusing state, delete the folder and rebuild it. It takes a minute and costs nothing, because everything in it is reproducible:
rm -rf .venv
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements.txt
That willingness to throw it away is itself the benefit.
Alternatives you will meet
The landscape has several tools, and they solve the same core problem:
venv— built in, no install, and what this course uses. Learn this first; everything else builds on the same idea.uv— much faster, increasingly popular, handles environments and packages together.- Poetry — environments plus dependency resolution and publishing.
- conda — common in data science, manages non-Python dependencies too.
Start with venv. It is always available, and understanding it makes the others
obvious.
Practice
- Create a project folder and a
.venvinside it. - Activate it and confirm your prompt changes.
- Run
python -c "import sys; print(sys.executable)"before and after activating. Compare. - Run
pip listinside a fresh environment. Note how little is there. - Install
requestsinside the environment. Import it successfully. Thendeactivateand try importing it again — read theModuleNotFoundErrorand explain it in one sentence. - Create two environments and install different versions of the same package in each. Confirm they do not interfere.
- Add
.venv/and__pycache__/to a.gitignoreand confirmgit statusstops mentioning them. - Delete an environment and rebuild it from scratch. Time how long it takes.
- Point VS Code at your
.venvinterpreter and confirm the status bar shows it.
Next: installing packages properly, and making sure the versions you tested against are the versions that run.
Stuck on this lesson?
Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.
About the internship