Intuition The one core idea
Your computer has one shared Python that every project must share — like one toy box for a whole house. A virtual environment is a private, empty copy of that box for a single project, so installing packages for one project can never disturb another. Everything in this topic is just this: make a private box, point your terminal at it, and keep a shopping list so you can rebuild the box anywhere.
This page assumes nothing . Before you touch the parent topic , every symbol, word, and squiggle it uses is built here from the ground up. Read top to bottom — each idea is a brick for the next.
Before any Python, we need the place where all these commands happen.
Definition Terminal / shell
A terminal (also called a shell ) is a text window where you type one instruction, press Enter, and the computer runs it . Instead of clicking icons, you type words.
The line you type into is called the prompt . It often ends in $ (Linux/Mac) or > (Windows). When you see a code block like:
python -m venv .venv
it means: type those words into the terminal and press Enter. The word bash just labels the language of the terminal — you don't type it.
Virtual environments are controlled entirely from the terminal . There is no button. So the picture above — a prompt where you type a command — is the stage on which the whole topic plays out.
Definition Python interpreter
Python here means one specific program file on your machine that reads .py code and executes it. When you type python, the terminal searches for that program and starts it.
Think of it as a translator you can call by name.
Imagine a single vending machine labelled python. Type its name, and out comes a running Python. The whole problem this topic solves is: there is only ONE such machine by default, shared by every project.
Here is the secret gear that makes virtual environments work at all.
PATH
==PATH== is an ordered list of folders the terminal searches, top to bottom, when you type a command name like python. It stops at the first folder that contains a program with that name.
Intuition Why order matters — this IS the trick
Look at the figure. If we sneak a new folder to the top of the PATH list, and that folder has its own python, the terminal finds that one first and never reaches the system Python below. Activating a virtual environment does exactly this: it puts the env's folder at the top of PATH. That single act redirects python and pip to the private copies. Remember this — the parent note's "activation edits your PATH" is nothing more than this picture.
Recall Check yourself
If two folders on PATH both contain python, which runs? ::: The one in the folder listed first (higher up) on PATH.
A package is a bundle of ready-made Python code someone else wrote (e.g. requests for downloading web pages) that you can install and reuse instead of writing it yourself.
site-packages
==site-packages== is the specific folder where installed packages get dropped. When your code says import requests, Python looks inside site-packages to find it.
Intuition The picture: one box vs many boxes
site-packages is the toy box. The whole problem: with a shared Python, there is one site-packages, so every project fights over it. A virtual environment gives each project its own site-packages folder. See the figure below.
pip
==pip== is a program (bundled with Python) whose job is to download a package and drop it into a site-packages folder . pip install requests means "fetch requests and put it in the active site-packages."
Where does pip download from ? From a giant online warehouse — see pip and PyPI for the full story. For now: pip = the delivery truck, site-packages = the shelf it stacks boxes on.
Intuition Why pip needs the PATH trick
pip installs into whichever site-packages belongs to whichever python is first on PATH. So if you activated your env (env at top of PATH), pip's boxes land in the env's box. If you forgot, they land in the shared system box — polluting it. This is why the parent note screams "check the prompt before pip install."
The parent note insists on python -m venv, never bare venv. Let's earn that -m.
-m module
-m is an option you give to python. python -m NAME means "run the built-in tool named NAME, using THIS python ."
-m and not just venv?
If you typed bare venv, the terminal would hunt the whole PATH for something called venv — and might find the wrong Python's copy. But python -m venv says "use the venv tool belonging to the exact python I just named ." So python3.11 -m venv guarantees the new env is a 3.11 env. -m pins the version by tying the tool to a specific interpreter.
Recall Check yourself
Why is python3.11 -m venv .venv safer than venv .venv? ::: -m runs the venv tool belonging to that exact Python (3.11), so the env is guaranteed to be a 3.11 env — no guessing which venv PATH finds.
venv ::: the built-in tool (python -m venv) that creates an environment folder.
environment (the env) ::: the resulting folder holding a private interpreter link + its own site-packages.
pyvenv.cfg ::: a tiny text file inside the env pointing back to the base Python (so it still finds the standard library).
bin/ or Scripts/ ::: the folder added to the top of PATH on activation; holds the env's python and pip.
activate ::: the action of putting bin//Scripts/ at the top of PATH for the current terminal.
Common mistake "The env contains a whole new downloaded Python."
Why it feels right: it "creates an interpreter."
Reality: it copies or links the Python you already ran. No download; the version is frozen to whichever python you typed.
requirements.txt
A plain text file listing package names and versions , one per line, so any machine can rebuild the same set of packages. It is the shopping list — not the packages themselves.
Two symbols show up in it:
== and >=
flask==3.0.3 — the ====== means exactly this version, no other. ("Pinned.")
flask>=3.0 — the ==>=== means this version or any newer one. ("At least.")
These are just the "equals" and "greater-or-equal" you know from arithmetic, applied to version numbers. Why version numbers have three parts like 3.0.3 is explained in Semantic versioning .
Intuition Why two styles exist
== gives reproducible builds — the same boxes every time, ideal for shipping. >= lets a library's users pull newer compatible versions automatically. The parent's Example 3 is exactly this choice.
sys.path
When Python starts it builds ==sys.path==, an ordered list of folders it searches for imports — with the active env's site-packages near the top. It is the inside-Python cousin of the terminal's PATH.
The full mechanics of how import walks this list live in Python import system and sys.path . For this topic, one fact matters: the active env's site-packages sits on sys.path, so import requests finds the env's copy first.
Everything above feeds the topic like this:
python -m venv creates env
requirements.txt shopping list
Virtual environment topic
Read it as: the terminal lets you run python; python plus -m venv builds the env folder; PATH order is what activation exploits; pip fills the env's site-packages; requirements.txt records what you filled it with. All arrows converge on the topic.
Once these bricks are solid, natural next steps in the vault are Dependency management — poetry, pipenv (smarter tools built on the same ideas), Reproducible builds and Docker (isolation taken further), and .gitignore best practices (why you never commit the .venv/ folder).
Self-test: can you answer each without peeking? If any stalls, reread that section.
What is a terminal, in one sentence? A text window where you type one instruction, press Enter, and the computer runs it.
What does python refer to on your machine? One specific program file that reads and runs .py code.
What is PATH and why does order matter? An ordered list of folders the terminal searches for a command; it uses the FIRST match, so putting a folder on top overrides everything below.
What is site-packages? The folder where installed packages are stored and where import looks for them.
What does pip install X do, and where does X land? Downloads package X and drops it into the site-packages of whichever python is first on PATH.
Why write python -m venv instead of bare venv? -m runs the venv tool of that exact python, pinning the env's interpreter version.
What lives inside a venv folder? A pyvenv.cfg pointing to base Python, a bin//Scripts/ folder (env's python + pip), and an empty site-packages.
What does "activate" physically do? Puts the env's bin//Scripts/ folder at the top of PATH for the current terminal only.
What is requirements.txt? A text file listing package names and versions so the env can be rebuilt anywhere.
Difference between ==3.0.3 and >=3.0? == means exactly that version; >= means that version or any newer one.