Virtual Environments and pip
When you work on multiple Python projects, you’ll quickly run into a problem: different projects need different versions of the same package. Project A needs Django 4.0, but Project B needs Django 5.0. Without isolation, you’d be constantly reinstalling packages or dealing with conflicts.
Virtual environments solve this. Each project gets its own isolated Python environment with its own installed packages. This guide shows you how to set them up and use them effectively.
Creating a Virtual Environment
Python ships with venv, a built-in module for creating virtual environments. Open your terminal and run:
python -m venv myproject-env
This creates a folder called myproject-env in your current directory. The name is up to you — venv, .venv, and env are common choices.
On Windows, the structure looks like this:
myproject-env/
├── Scripts/
│ ├── activate.bat
│ ├── activate
│ ├── python.exe
│ └── pip.exe
├── Lib/
│ └── site-packages/
└── pyvenv.cfg
On macOS and Linux, it’s bin/ instead of Scripts/.
Activating the Environment
Before installing packages, you need to activate the environment. This ensures any python or pip commands run against the isolated environment, not your system Python.
On Windows:
myproject-env\Scripts\activate
On macOS and Linux:
source myproject-env/bin/activate
When activated, your terminal prompt changes to show the environment name:
(myproject-env) C:\Users\You\projects\myproject>
Now, any package you install goes into this isolated environment, not your global site-packages.
Installing Packages with pip
Once activated, use pip to install packages:
pip install requests
This installs the requests library into your virtual environment. You can verify the installation:
import requests
print(requests.__version__)
You can install specific versions:
pip install flask==3.0.0
pip install django>=4.0,<5.0
To upgrade a package:
pip install --upgrade requests
And to uninstall:
pip uninstall requests
Freezing and Installing from Requirements
When you share your project or deploy it, others need to know which packages to install. That’s where requirements.txt comes in.
Generating Requirements
Capture all installed packages and their versions:
pip freeze > requirements.txt
This creates a file that looks like:
requests==2.31.0
flask==3.0.0
werkzeug==3.0.1
Installing from Requirements
Someone cloning your project can install all dependencies with one command:
pip install -r requirements.txt
Splitting Requirements
For larger projects, you might split requirements:
requirements.txt— production dependenciesrequirements-dev.txt— testing and development tools
# Install production only
pip install -r requirements.txt
# Install everything including dev dependencies
pip install -r requirements.txt -r requirements-dev.txt
Best Practices
A few things will save you headaches down the road.
Keep virtual environments outside your project folder. It’s cleaner to have all your venvs in one place:
mkdir ~/venvs
python -m venv ~/venvs/myproject
source ~/venvs/myproject/bin/activate
Add your virtual environment to .gitignore. You never want to commit a virtual environment to version control — it’s huge and machine-specific:
# In your .gitignore
myproject-env/
venv/
.venv/
Use a consistent location for all your venvs. ~/.virtualenvs/ or ~/venvs/ are common choices. It makes it easier to find and clean them up later.
Deactivating and Cleaning Up
When you’re done working in a virtual environment:
deactivate
This returns you to the global Python. The virtual environment folder stays on disk until you delete it.
To remove a virtual environment entirely:
# First deactivate if active
deactivate
# Then delete the folder
rm -rf myproject-env # Linux/macOS
rmdir /s /q myproject-env # Windows
Common Issues
“python” command not found after activation. On some systems, you need to use python3 instead of python. Check what’s available:
which python
which python3
pip not found after activation. Try:
python -m pip install requests
This runs pip as a module, which works even if the pip executable isn’t in your PATH.
Permission denied errors. Never use sudo pip install — it installs packages system-wide and causes permission and security issues. Always use a virtual environment instead.
When You Don’t Need Virtual Environments
Virtual environments are essential when you’re installing packages or working on multiple projects. But for simple scripts that only use the standard library, you don’t need one. Similarly, if you’re just experimenting in the Python interpreter, you can skip it.
That said, it’s a good habit to create a venv even for small projects. Future-you will appreciate it when you need to install that one extra package.
Summary
Virtual environments give each Python project its own isolated space for dependencies. Use python -m venv to create one, activate it with the appropriate command for your OS, and install packages with pip. Capture dependencies with pip freeze and restore them with pip install -r requirements.txt.
Keep your venvs outside your project folders and add them to .gitignore. This workflow is the foundation for clean, reproducible Python projects.
In the next guide in this series, you’ll learn about pyproject.toml and modern Python packaging — the current standard for defining project metadata and dependencies.