Virtual Environments

A virtual environment is an isolated, per-project Python installation that keeps each project's packages and versions separate, so dependencies never clash and your installs stay reproducible.

Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.

Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

Master professional Python dependency management, virtual environments, and reproducible installs.

This lesson teaches how to build professional Python applications with:

This separates "it works on my laptop" scripts from real, deployable software.

🔥 1. Why You Should Never Rely on "System Python"

On most machines, you'll have System Python (used by OS tools) and Your project Python (what you control).

If you install packages globally with pip install requests , you risk:

Rule #1: Each serious project gets its own isolated environment.

🧪 2. What a Virtual Environment Actually Is

No conflict, because they use different environments.

⚙️ 3. Creating a Virtual Environment (venv)

🧱 4. Best Practices for Environment Layout

Never commit your virtual environment to Git.

💊 5. Installing Packages the Right Way

Avoid installing directly with pip outside an activated environment.

📦 6. requirements.txt & Pinning Versions

For reproducibility, you want to freeze exactly which versions you're using.

🔍 7. Semantic Versioning & Safer Constraints

Not all dependencies need to be fully pinned, but you should understand version ranges:

For libraries you publish: allow ranges (e.g. >=1.4,<2.0)

For apps you deploy: pinned versions (==) are safest

🧪 8. Separating Runtime vs Dev Dependencies

Don't ship your test tools to production. Use two files:

Your production environment only installs requirements.txt, keeping it:

🧰 9. Using pip-tools / Poetry / UV (Modern Workflows)

As projects get bigger, plain pip freeze becomes messy. Three common modern approaches:

This ensures your environment matches exactly the file.

Uses pyproject.toml + poetry.lock. You define high-level deps; Poetry resolves & locks everything.

🌍 10. Global Python Tools: Use pipx, Not Your Project venv

Some Python packages are tools, not libraries, e.g.:

These are better installed with pipx globally:

🧠 11. Environment Rebuild Strategy

This rebuild pattern is common in real teams.

🧩 12. Solving Dependency Conflicts Like a Pro

This is a dependency conflict — two packages require incompatible versions of a dependency.

🧱 13. Lockfiles & Reproducible Installs

Keep human-friendly requirements in requirements.in:

It produces requirements.txt with all sub-dependencies pinned.

Keep one simple file for what you WANT, another for the exact resolved versions you MUST use.

🧬 14. Per-Environment Dependencies (Dev, Test, Production)

🔐 15. Internal Libraries & Private Packages

Businesses often create reusable internal libraries. These can be installed:

🛡 16. Security & Supply-Chain Safety

Dependencies are attack vectors. Follow these rules:

Floating version ranges can pull in a bad update.

Small dependency trees = safer, easier to maintain.

🐳 17. Using Virtual Environments Inside Docker

Docker isolates processes, but venvs add clarity and consistency.

Local + Docker both use .venv → consistent setup.

⚙️ 18. Clean Install Testing in CI Pipelines

🧠 19. Workflow & Naming Conventions

🎯 20. The Master Mental Model

Everything you do around dependencies fits into this model:

Python version → Virtual Environment → Dependencies → Lockfile

🧪 21. Example: Clean Setup Workflow for a New Project

A solid, repeatable pattern for any new Python project:

🏗 22. Example: Multi-Service Environment Structure

For a slightly bigger setup (e.g. API + worker + shared library):

Each service can have its own virtual environment:

Shared library can be installed in editable mode:

This keeps boundaries clear, especially when different services need different versions of frameworks.

Practice quiz

What is the standard-library command to create a virtual environment named .venv?

  • pip install venv .venv
  • python -m virtualenv create
  • python -m venv .venv
  • venv new .venv

Answer: python -m venv .venv. venv ships with Python; 'python -m venv .venv' creates a .venv/ folder containing its own interpreter and site-packages.

On macOS/Linux, how do you activate a virtual environment in .venv?

  • source .venv/bin/activate
  • .venv/Scripts/Activate.ps1
  • activate .venv
  • python -m venv activate

Answer: source .venv/bin/activate. On Unix shells you source the activate script: 'source .venv/bin/activate'. The PowerShell .ps1 form is for Windows.

What is the main reason to install packages with 'python -m pip' instead of just 'pip'?

  • It installs packages faster
  • It automatically pins versions
  • It is the only way to use requirements.txt
  • It guarantees you use the pip tied to that specific Python interpreter

Answer: It guarantees you use the pip tied to that specific Python interpreter. 'python -m pip' guarantees you invoke the pip bound to that interpreter, avoiding 'wrong pip' issues across multiple Pythons.

Which command captures your installed packages and versions into a requirements file?

  • pip list > requirements.txt
  • pip freeze > requirements.txt
  • pip export requirements.txt
  • pip save requirements.txt

Answer: pip freeze > requirements.txt. 'pip freeze' prints installed packages with exact versions in requirements format; redirecting it writes requirements.txt.

What does the version specifier '==1.4.3' mean in a requirements file?

  • Exactly version 1.4.3 only
  • Any 1.x version
  • Version 1.4.3 or newer
  • Compatible release, 1.4.x only

Answer: Exactly version 1.4.3 only. '==1.4.3' pins the exact version — the safest choice for deployed production apps.

Why should the .venv/ folder be added to .gitignore?

  • Because Git cannot store binary files
  • Because Git would corrupt the interpreter
  • Because the environment is large, machine-specific, and recreatable from requirements.txt
  • Because pip refuses to run inside a Git repo

Answer: Because the environment is large, machine-specific, and recreatable from requirements.txt. The venv is rebuildable from requirements.txt and is OS/path-specific, so you never commit it — you commit the requirements instead.

Which tool is recommended for installing global Python CLI tools like httpie or black in isolation?

  • pip
  • pipx
  • venv
  • poetry

Answer: pipx. pipx installs each CLI tool in its own isolated environment and exposes it on your PATH, keeping tools separate from project deps.

In a pip-tools workflow, what is the role of a requirements.in file?

  • It is the fully pinned lockfile
  • It lists only dev tools
  • It is an alias for the activate script
  • It holds high-level human-friendly dependencies that get compiled into a pinned requirements.txt

Answer: It holds high-level human-friendly dependencies that get compiled into a pinned requirements.txt. requirements.in lists what you WANT; 'pip-compile' resolves and pins everything (including sub-deps) into requirements.txt.

A teammate gets ModuleNotFoundError for a package you installed. What is the most likely cause?

  • Python itself is broken
  • The virtual environment wasn't activated or the wrong interpreter is selected
  • The package no longer exists on PyPI
  • requirements.txt must be deleted

Answer: The virtual environment wasn't activated or the wrong interpreter is selected. Usually the venv isn't activated, or the IDE points at a different interpreter, so the install went to the wrong Python.

Why is storing times — and dependencies — for production best done with pinned (==) versions?

  • Pinned versions make installs slower but smaller
  • Pinned versions auto-upgrade on deploy
  • Pinned versions ensure reproducible, identical installs across every machine
  • Pinned versions are required by venv

Answer: Pinned versions ensure reproducible, identical installs across every machine. Exact pins give reproducible builds: every machine and CI run installs the same versions, eliminating 'works on my laptop' drift.