How to Install and Use Multiple Python Versions

You can install multiple Python versions side by side, each in its own folder. On Windows, the Python install manager (py install 3.11) adds versions and py -3.11 picks one. On any system, uv or pyenv install and switch them for you.

py install 3.11                     # Windows: Python install manager
py -3.11 script.py                  # run with that version
uv python install 3.11 3.13         # any OS: uv downloads and manages them
pyenv install 3.11                  # macOS / Linux: pyenv

For the screenshots, this machine has Python 3.12 from python.org plus 3.11 and 3.13 installed with uv 0.12.22, all on Windows in a real Command Prompt.

Below you’ll see the same script behaving differently on each version, then how to choose a version per command, per virtual environment and per project folder.

Why install more than one Python version?

Mostly because projects don’t all move at once. A work project might be pinned to 3.11 while you try 3.13 at home, and a library may not support the newest release yet.

Versions really do differ. This script uses itertools.batched(), which arrived in Python 3.12, and runs it on three versions:

import itertools
import sys

v = sys.version_info
print(f"Python {v.major}.{v.minor}.{v.micro}", end="  |  ")

if hasattr(itertools, "batched"):
    print("itertools.batched:", list(itertools.batched("ABCDEF", 2)))
else:
    print("itertools.batched: not available (added in 3.12)")

Command Prompt output:

Python 3.12.5  |  itertools.batched: [('A', 'B'), ('C', 'D'), ('E', 'F')]
Python 3.11.17  |  itertools.batched: not available (added in 3.12)
Python 3.13.16  |  itertools.batched: [('A', 'B'), ('C', 'D'), ('E', 'F')]
Command Prompt running the same Python script on 3.12 with the py launcher and on 3.11 and 3.13 by full path, where 3.11 lacks itertools.batched
Same file, three interpreters. Only 3.11 is missing itertools.batched().

The first command uses the Windows py launcher; the other two run each interpreter by its full path. That’s the core idea: each version is a separate program, and you choose which one runs your code.

How to install multiple Python versions on Windows

Since Python 3.14, python.org recommends the Python install manager. Get it from python.org/downloads or the Microsoft Store, and it gives you one py command for installing and choosing versions:

py install 3.11        # install a version
py install 3.13
py list                # see what's installed
py -3.11 script.py     # run with a specific version (py -V:3.11 also works)
py -3.13 -m pip install tabulate   # pip for that version

The older setup, one python.org installer per version, still works and is what this machine uses. Those installers are now deprecated, though, and python.org won’t produce them for Python 3.16 or later.

Either way, py -3.11 runs 3.11. I’d only let one version own the plain python command and reach the others through py -X.Y.

And always install packages with py -X.Y -m pip, or they’ll land in the wrong version. ModuleNotFoundError after pip install is exactly that mix-up.

Create a virtual environment with a specific Python version

A virtual environment remembers the Python that created it. Create it with the version you want, and everything run inside it uses that version:

import itertools
import sys

v = sys.version_info
print(f"Python {v.major}.{v.minor}.{v.micro}", end="  |  ")

if hasattr(itertools, "batched"):
    print("itertools.batched:", list(itertools.batched("ABCDEF", 2)))
else:
    print("itertools.batched: not available (added in 3.12)")

Command Prompt output:

Python 3.11.17  |  itertools.batched: not available (added in 3.12)
Command Prompt creating a Python virtual environment with the 3.11 interpreter and running a script inside it on Python 3.11
The environment was built from 3.11, so the script ran on 3.11.

With the py command, that’s py -3.11 -m venv env311. This is how I keep old projects on old versions without thinking about it. Virtual environments in Python covers activating and managing them.

Install and switch Python versions with uv

uv is a fast, cross-platform tool that installs Python versions for you, with no installers to click through. It can also pin a version to a project folder, so uv run picks it automatically:

import itertools
import sys

v = sys.version_info
print(f"Python {v.major}.{v.minor}.{v.micro}", end="  |  ")

if hasattr(itertools, "batched"):
    print("itertools.batched:", list(itertools.batched("ABCDEF", 2)))
else:
    print("itertools.batched: not available (added in 3.12)")

Command Prompt output:

cpython-3.13.16-windows-x86_64-none    C:\pyguides\uvpython\cpython-3.13-windows-x86_64-none\python.exe
cpython-3.11.17-windows-x86_64-none    C:\pyguides\uvpython\cpython-3.11-windows-x86_64-none\python.exe
Pinned `.python-version` to `3.11`
Python 3.11.17  |  itertools.batched: not available (added in 3.12)
Updated `.python-version` from `3.11` -> `3.13`
Python 3.13.16  |  itertools.batched: [('A', 'B'), ('C', 'D'), ('E', 'F')]
Command Prompt showing uv python list with two installed versions, uv python pin writing .python-version, and uv run using 3.11 then 3.13
uv python pin writes a .python-version file, and uv run follows it.
python -m pip install uv          # or the standalone installer from Astral
uv python install 3.11 3.13       # download and install both
uv python list --only-installed   # see what you have
uv python pin 3.11                # this folder uses 3.11 from now on

Commit the .python-version file and everyone on the project gets the same version. pyenv reads the same file name, which makes the two tools easy to mix on a team.

Multiple Python versions on macOS and Linux

The system Python on macOS and Linux belongs to the operating system, so leave it alone and add your own versions next to it. The common choices are:

ToolInstall a versionChoose one
uvuv python install 3.11uv python pin 3.11, uv run
pyenvpyenv install 3.11pyenv local 3.11 (writes .python-version)
Homebrew (macOS)brew install python@3.11Run python3.11 directly
python.org (macOS)The installer for each versionpython3.11, python3.13

On these systems each version gets a versioned command, so python3.11 -m pip install tabulate is the reliable way to install for one specific version.

How do I check which Python version I’m using?

Run python --version, or print sys.version from inside the script, which tells you what’s actually running your code. Checking your Python version lists every way to do it.

If the version isn’t the one you expected, the usual cause is PATH order: the first python found on PATH wins. Use py -X.Y, a versioned command or an activated virtual environment instead of relying on it.

Multiple Python versions: quick reference

GoalWindows (py)uv (any OS)
Install a versionpy install 3.11uv python install 3.11
List installed versionspy listuv python list --only-installed
Run a script on 3.11py -3.11 script.pyuv run --python 3.11 script.py
Install a package for 3.11py -3.11 -m pip install pkguv pip install pkg inside a 3.11 venv
Virtual environment on 3.11py -3.11 -m venv .venvuv venv --python 3.11
Pin a folder to 3.11Not built inuv python pin 3.11

Working through a Python setup? These guides help with the next steps:

Frequently asked questions

Can I have multiple versions of Python installed?

Yes. Each version installs into its own folder. On Windows, the Python install manager installs them and py -X.Y picks one; on any OS, uv or pyenv manage them for you.

How do I run a script with a specific Python version on Windows?

Use py -3.11 script.py. Run py list to see installed versions, or py --list with the older launcher.

How do I install a package for a specific Python version?

Run pip through that interpreter: py -3.11 -m pip install package on Windows, or python3.11 -m pip install package on macOS and Linux.

How do I create a virtual environment with a specific Python version?

Create it with that interpreter: py -3.11 -m venv .venv, or uv venv --python 3.11.

Does installing a new Python version remove the old one?

No. Installing 3.13 leaves 3.11 in place. A patch update within the same minor version, such as 3.12.4 to 3.12.5, replaces it.

What does the .python-version file do?

It records which Python version a folder should use. uv and pyenv both read it. The Python install manager documentation covers how py installs and picks versions on Windows.