Python Virtual Environments & pip
A virtual environment is an isolated Python installation for a single project. It keeps each project’s packages separate so versions never clash, and it keeps your global Python clean. pip is the tool that installs and manages those packages. (For installing Python itself, see the Installation page.)
Golden rule: one virtual environment per project, and never
pip installinto your system Python.
flowchart TD A["python -m venv .venv"] --> B[".venv/ with its own site-packages"] B --> C["pyvenv.cfg records the base interpreter"] D["activate"] --> E["puts .venv/bin (Scripts) first on PATH"] E --> F["'python' and 'pip' now resolve INSIDE the venv"] F --> G["pip install writes to .venv/site-packages"] H["sys.prefix"] --> I["the venv directory"] J["sys.base_prefix"] --> K["the original install -- unchanged"] I --> L["prefix != base_prefix -> you are in a venv"] K --> L
Why isolate?
Section titled “Why isolate?”Without isolation, every project shares one set of packages:
- Project A needs
django==3.2, Project B needsdjango==4.2— they can’t coexist globally. - A global install can break system tools that rely on specific versions.
- You can’t reproduce “exactly what this project needs” for a teammate or server.
A virtual environment solves all three.
Creating an environment with venv
Section titled “Creating an environment with venv”venv ships with Python. Create an environment (commonly named .venv) in your project folder:
# Create a virtual environment in the .venv folder
python -m venv .venvThis makes a .venv/ directory containing a private copy of Python and a place for packages.
Activating and deactivating
Section titled “Activating and deactivating”You must activate the environment so python and pip point at it.
source .venv/bin/activate.venv\Scripts\Activate.ps1Once active, your prompt usually shows (.venv). To leave it:
deactivateTip: add
.venv/to your.gitignore— environments are rebuilt fromrequirements.txt, not committed.
Installing packages with pip
Section titled “Installing packages with pip”With the environment active:
pip install requests # latest version
pip install "django==4.2" # a specific version
pip install "flask>=2,<3" # a version range
pip install --upgrade requests # upgrade to the newest
pip uninstall requests # remove a package| Command | Does |
|---|---|
pip install NAME | Install the latest version. |
pip install NAME==X.Y | Install an exact version. |
pip install --upgrade NAME | Upgrade a package. |
pip uninstall NAME | Remove a package. |
pip list | List installed packages. |
pip show NAME | Show details about a package. |
requirements.txt — reproducible installs
Section titled “requirements.txt — reproducible installs”Record exact versions so anyone can recreate the environment.
# Save the current environment's packages
pip freeze > requirements.txt
# Recreate it elsewhere (in a fresh venv)
pip install -r requirements.txtA requirements.txt looks like:
requests==2.31.0
flask==3.0.0
python-dotenv==1.0.0A typical project workflow
Section titled “A typical project workflow”mkdir myproject && cd myproject
python -m venv .venv
source .venv/bin/activate # (Windows: .venv\Scripts\Activate.ps1)
pip install requests flask
pip freeze > requirements.txt
# ... write code ...
deactivateCommon pitfalls
Section titled “Common pitfalls”- Forgetting to activate —
pip installthen lands in global Python. Check your prompt for(.venv). - Committing
.venv/— it’s large and machine-specific; commitrequirements.txtinstead. - Mixing
pipand the system package manager — inside a venv, always usepip. pythonvspython3— on some systems the command ispython3; the same goes forpip/pip3.
Practice Exercises
Section titled “Practice Exercises”These run plain Python that mirrors what the tools do under the hood.
Exercise 1 – Check the running Python version
Section titled “Exercise 1 – Check the running Python version”Exercise 2 – Parse a requirements line
Section titled “Exercise 2 – Parse a requirements line”Exercise 3 – Build a pip install command
Section titled “Exercise 3 – Build a pip install command”Check yourself
Section titled “Check yourself”-
How do you reliably detect that code is running inside a virtual environment?
Verified on both interpreters here. `VIRTUAL_ENV` is set by the activate SCRIPT, so it is absent when a cron job or service runs the venv's interpreter by full path — which is the usual deployment shape.
pch.quizShowAnswer
B — Compare `sys.prefix` with `sys.base_prefix` — Verified on both interpreters here. `VIRTUAL_ENV` is set by the activate SCRIPT, so it is absent when a cron job or service runs the venv's interpreter by full path — which is the usual deployment shape.
-
What does `sys.base_prefix` point at inside a venv?
A venv is not a copy of Python — the interpreter is still the base one. That is exactly what makes the two-variable comparison work as a test.
pch.quizShowAnswer
B — The original Python installation — A venv is not a copy of Python — the interpreter is still the base one. That is exactly what makes the two-variable comparison work as a test.
-
What does activating a virtual environment actually do?
It is PATH manipulation plus a prompt change. `/path/.venv/bin/python script.py` uses the venv with no activation at all.
pch.quizShowAnswer
B — Puts the venv's script directory first on `PATH` — It is PATH manipulation plus a prompt change. `/path/.venv/bin/python script.py` uses the venv with no activation at all.
-
Why does a cron job often fail with `ModuleNotFoundError` when the same command works in your shell?
Use the absolute interpreter path — `/path/.venv/bin/python` — rather than relying on activation. The same reasoning covers the working directory, which is HOME rather than your project.
pch.quizShowAnswer
B — Cron does not run your shell, so no venv is activated and PATH is minimal — Use the absolute interpreter path — `/path/.venv/bin/python` — rather than relying on activation. The same reasoning covers the working directory, which is HOME rather than your project.
Summary
Section titled “Summary”- A virtual environment isolates one project’s packages; create it with
python -m venv .venv. - Activate it before working (
source .venv/bin/activateorActivate.ps1),deactivateto leave. - Use pip to
install,upgrade,uninstall, andlistpackages. - Pin versions with
pip freeze > requirements.txtand restore withpip install -r requirements.txt. - Commit
requirements.txt, not the.venv/folder.
pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading