Python Tutorial: virtualenv and why you should use virtual environments
Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
Use virtual environments to isolate dependencies so one project’s package upgrades don’t break others that need different versions.
Briefing
Virtual environments (virtualenv) let Python developers isolate dependencies per project, preventing package upgrades from breaking other applications that rely on different versions. Instead of sharing one global set of installed libraries, each project can run inside its own environment with only the packages—and specific versions—that project needs. That isolation matters most when multiple apps depend on the same framework (like Flask or Django) but require different releases; upgrading a shared global dependency can silently break working sites.
The tutorial demonstrates the workflow end to end. After confirming that global site-packages contain many libraries at fixed versions, it creates a dedicated folder named “environments” to store virtual environments. Inside that directory, it runs `virtualenv project1orEnv` to create the first environment. Creating the environment automatically installs tooling like `pip` and `setuptools`, so the new environment is immediately ready for package installation.
Activation is handled through a shell command: `source <env-name>/bin/activate`. Once activated, the environment name appears in the command prompt, and `which python` and `which pip` point to executables inside the environment’s directory. A `pip list` now shows only the packages installed within that environment—initially just `pip` and `setuptools`. The tutorial then installs libraries (including `numpy`, `psycopg2`, and `pytz`), verifies them with another `pip list`, and captures the exact installed versions using `pip freeze`.
To move those dependencies to another machine or project, it writes the frozen output to `requirements.txt` (via `pip freeze > requirements.txt`). Later, another environment can recreate the same dependency set by running `pip install -r requirements.txt`, ensuring version consistency.
Switching back to the global Python setup is as simple as running `deactivate`, which removes the environment prompt marker and restores access to the global `python` and global installed packages. The tutorial also shows how to remove an environment entirely by deleting its folder (e.g., `rm -rf project1orEnv`).
Finally, it creates a second environment that targets a specific Python version using `virtualenv` with a Python interpreter path (it demonstrates `python2.6`), activates it, checks the interpreter version, and installs the earlier `requirements.txt` contents to match dependencies precisely.
A key practical note closes the loop: virtual environments are for dependencies, not for housing project source code. Developers should keep application files outside the environment and use the environment only to manage packages and versions that can be discarded or recreated safely.
Cornell Notes
Virtual environments isolate Python dependencies so different projects can use different package versions without interfering with each other. After creating an environment with `virtualenv`, activating it changes which `python` and `pip` executables are used, and `pip list` shows only that environment’s installed packages. Dependencies can be exported with `pip freeze` into a `requirements.txt` file and later installed in another environment using `pip install -r requirements.txt`. Running `deactivate` returns to the global Python setup, and deleting the environment folder removes the isolated packages entirely. Virtual environments manage dependencies only; project code should live outside them.
Why can upgrading a global package break multiple projects, and how does virtualenv prevent that?
What changes after activating a virtual environment, and how can you verify it?
How do you capture exact dependency versions from one environment for reuse elsewhere?
How do you recreate the same dependencies in a new virtual environment?
How do you switch back to global Python and remove an environment completely?
How can a virtual environment be tied to a specific Python version?
Review Questions
- What specific commands confirm that `python` and `pip` are coming from the active virtual environment rather than the global installation?
- How does `pip freeze` differ from `pip list`, and why does `requirements.txt` matter for reproducibility?
- What is the correct workflow for switching projects using virtualenv, and what should never be placed inside the environment?
Key Points
- 1
Use virtual environments to isolate dependencies so one project’s package upgrades don’t break others that need different versions.
- 2
Create environments in a dedicated directory (like an “environments” folder) to keep them organized.
- 3
Activate an environment with `source <env>/bin/activate` and verify isolation using `which python` and `pip list`.
- 4
Export exact dependency versions with `pip freeze > requirements.txt` and recreate them with `pip install -r requirements.txt`.
- 5
Switch back to global Python using `deactivate`, and remove an environment by deleting its folder.
- 6
Virtual environments manage dependencies only; keep project source code outside the environment directory.
- 7
Create Python-version-specific environments by pointing virtualenv at the desired interpreter (e.g., `python2.6`).