overview
Managing multiple Python versions cleanly is essential for working across
different projects or teams. In this post, I will walk through how to
install and manage Python versions with
pyenv on
Linux (or a Chromebook) and how to use a specific version with virtual
environments.
managing multiple Python versions
When working across different projects, you may need to use multiple
Python versions locally. There are several approaches:
-
version managers (recommended):
pyenv
(and pyenv-win for Windows) is a popular tool for switching between
different Python versions. It installs Python versions in isolated
directories and allows you to set global, local (project-specific), or
shell-specific Python versions.
-
manual installation: you can download and install
different Python versions directly from
python.org.
For this guide, we will use
pyenv
because it allows you to manage and switch between multiple Python
versions without interfering with the system Python that the OS relies on.
The installation process requires only a few steps.
-
First, install the required
pyenv
dependencies:
sudo apt update
sudo apt install -y build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncurses5-dev libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev
-
Then install
pyenv
via curl:
curl https://pyenv.run | bash
-
You can now configure your shell (~/.bashrc or ~/.zshrc) so
pyenv
can manage multiple Python versions and virtual environments. Ensure
you restart your terminal so the changes take effect.
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init --path)"
eval "$(pyenv virtualenv-init -)"
-
Finally, install the desired Python version:
-
As a quick sanity check, you can verify which Python versions are
installed locally:
And, voilà! In only a few steps we installed a new Python version with
pyenv. Each
version is isolated and completely separate from the system Python.
Now that we have multiple Python versions installed locally, let's take a
look at how Python organizes its files on the machine.
python file structure
Before diving into virtual environments, it is useful to understand how
Python organizes its system files and versions on a local machine. The
diagram below refers to the Python file structure on a Chromebook.
/
├── usr/
│ └── bin/
│ └── python3 <- system Python (DO NOT TOUCH)
│
├── home/
│ └── luisa/
│ ├── .bashrc
│ ├── .profile
│ ├── .pyenv/
│ │ ├── versions/
│ │ │ ├── 3.12.12/ <- newly installed Python version 3.12.12
│ │ │ │ ├── bin/
│ │ │ │ │ ├── python <- Python 3.12.12 interpreter
│ │ │ │ │ └── pip
│ │ │ │ └── lib/
│ │ │ └── 3.11.1/ <- another Python version
│ │ └── shims/
│ └── projects/
│ └── my_project/
│ ├── .python-version <- pyenv local version
│ ├── venv/ <- virtual environment folder
│ │ ├── bin/
│ │ │ ├── python <- venv Python, based on pyenv version
│ │ │ └── pip
│ │ └── lib/
│ ├── main.py
│ └── requirements.txt
As you can see, Python files are stored under different directories across
the machine, and each file has a different scope and purpose.
system python
On most Linux systems,
/usr/bin/python3 points to the
system-managed Python interpreter that comes with the operating system. An
interpreter is the program you run when you type
python3 in the terminal. This file should
never be touched, as modifying it could break system tools.
├── usr/
│ └── bin/
│ └── python3
...
newly installed python versions
When you install other Python versions (via tools like pyenv, Anaconda, or
manual builds), each installation includes its own
python3 executable located in a different
directory. By adjusting your
PATH environment variable—or by using a
version manager like pyenv—you control which
python3 executable runs when you type
python3 in your terminal.
From the tree diagram we can see that additional versions of Python are
generally installed in the home directory at
/home/user/.pyenv/versions/. So, the
actual path to the interpreter for the newly installed version becomes
~/.pyenv/versions/3.12.12/bin/python.
├── home/
│ └── luisa/
│ ├── .bashrc
│ ├── .profile
│ ├── .pyenv/
│ │ ├── versions/
│ │ │ ├── 3.12.12/
│ │ │ │ ├── bin/
│ │ │ │ │ ├── python
│ │ │ │ │ └── pip
│ │ │ │ └── lib/
│ │ │ └── 3.11.1/
│ │ └── shims/
...
virtual environments
Now that we understand how Python stores files and interpreters for
different versions, how do we select one of the installed versions for our
projects? This is where virtual environments (venvs for short) come into
play.
A
virtual environment (or
venv) is a self-contained directory that
contains:
-
a copy of the Python interpreter (the version is specified in the
.python-version file)
-
its own lib folder where
project-specific packages are installed.
Using a
venv ensures that each project
can manage its dependencies independently, preventing conflicts between
projects that require different versions of the same library.
The steps to activate a specific version of Python in a project are quite
straightforward.
-
First, select a version in the active shell:
-
Then create a virtual environment:
-
Finally, activate the virtual environment and install a
version-specific package:
source venv/bin/activate
.\venv\Scripts\Activate.ps1
pip install Flask==2.3.2
pip show Flask
pip freeze > requirements.txt
With these steps, you now have a project-specific virtual environment
that:
- uses the exact Python version you selected via pyenv
-
maintains its own set of installed packages independent of other
projects
-
can be easily reproduced on another machine using
`requirements.txt`
By combining
pyenv and
venvs, you gain full control over your
Python setup. Each project can safely use different Python versions and
package versions without interfering with each other or the system Python.
recap
In this tutorial, we learned to install different versions of Python on
the same machine, and apply a specific version to a project.
We learned that Python versions are the interpreters themselves, and each
version is installed separately. They exist independently of any specific
project and are stored in isolated directories, separate from the system
Python.
Virtual environments are instead project-specific containers that include
a copy of a chosen Python interpreter along with their own directory for
installed packages. A virtual environment doesn’t install a new Python
version; instead, it uses an existing one and creates an isolated
workspace so that each project can manage its dependencies without
affecting others.
I hope that with this tutorial you have expanded your Python toolbox, and
built the confidence to manage different Python versions and select the
right one for your personal projects.
Until next time!