
This article contains affiliate links. See my affiliate disclosure for more information.
Beginners should install Python with the official python.org installers. But the installer workflow isn&apost very efficient for professional developers working on multiple projects — or any project that supports multiple Python versions.
In this guide, I&aposll show you how to:
pyenv.black and flake8 with pipx.pip-tools.pyenvpyenv allows you to install multiple versions of Python and switch between them as needed. To install pyenv, run the command below that corresponds to your OS.
macOS/Linux
Use the automatic installer below, or see the README for more options:
curl https://pyenv.run | bashYou&aposll need to restart your shell when you&aposre done:
exec "$SHELL"Windows
Install with PowerShell below, or see the README for more options:
Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/pyenv-win/pyenv-win/master/pyenv-win/install-pyenv-win.ps1" -OutFile "./install-pyenv-win.ps1"; &"./install-pyenv-win.ps1"pyenv is only compatible with Unix/Linux operating systems. Windows users must use the separately maintained pyenv-win fork. pyenv and pyenv-win share the same CLI commands, so this guide works for every OS.Once pyenv or pyenv-win is installed, run pyenv install 3.11 to install the latest version of Python 3.11:
pyenv install 3.11At the time of the writing, the latest version is 3.11.1.
Use a different version prefix or a specific version number to install other versions of Python. For example, the following command installs the latest version of Python 3.10:
pyenv install 3.10To use a specific Python version that you&aposve installed, run python global:
pyenv global 3.11.1Now your python3 command points to Python 3.11.1.
.python-version containing a specific Python version number in your project&aposs root directory. Whenever you cd into the project&aposs folder, pyenv will automatically switch your interpreter to the version specified in .python-version.pipxpipx is a Python package installer that installs applications and command-line utilities in isolated environments and makes them available globally.
This is particularly helpful for tools like black and flake8, as they can be installed once and used across multiple projects while still taking into account project-specific configuration files.
You can install pipx with pip:
python3 -m pip install pipxBefore you can use pipx, you need to add it to PATH:
python3 -m pipx ensurepathpipx links applications it installs to the same Python executable that was originally used to install pipx.pipx, those applications will run using the pipx Python executable. (Except for ipython, which will detect and use project-specific virtual environments.)pipx Python executable renders any pipx-installed tools pointing to it unusable.pipx for every version of Python that you install with pyenv.Some of the tools I install with pipx are:
black: My preferred Python auto-formatter.flake8: My preferred Python code linter.ipython: My preferred Python REPL.The following commands install all three tools in three separate environments:
pipx install blackpipx install flake8pipx install ipythonNow you can use these tools as you normally would across all your projects without installing them in every project&aposs environment.
If you use Python for VS Code, you&aposll need to point your flake8 path to the right location. If you don&apost, you&aposll see a pop-up that says "flake8 is not installed" every time you open VS Code.
Run pipx list to list every app installed by pipx. The application install path is displayed on the second line of output:
$ pipx listvenvs are in /Users/damos/.local/pipx/venvsapps are exposed on your $PATH at /Users/damos/.local/bin package black 22.12.0, installed using Python 3.11.1 - black - blackd package flake8 6.0.0, installed using Python 3.11.1 - flake8 package ipython 8.9.0, installed using Python 3.11.1 - ipython - ipython3In my case, apps are installed in /Users/damos/.local/bin. Now run which flake8 to see which executable the flake8 command points to:
$ which flake8/Users/damos/.local/bin/flake8Copy this path to your clipboard.
which flake8 should show flake8 in the same directory that pipx uses to install applications.flake8 with a Python version that isn&apost managed by pyenv. In this case, you&aposll need to uninstall the old version of flake8 or remove the old version of Python.Open the VS Code settings explorer by going to File > Settings menu or pressing Cmd+, on macOS or Ctrl+, on Linux/Windows.
Type flake8 into the search bar and press Enter. Then paste the path to flake8 into the input box for the Python > Linting: Flake8 Path setting:

settings.json by editing the python.linting.flake8Path setting.pip-toolsI only had to use pip-tools for about 5 minutes to know I needed it all the time. pip-tools helps you where you need it to and gets out of the way everywhere else. The basic usage goes like this.
Start a new Python project in a new folder:
# Create a new folder and change directories to itmkdir ~/my-project && cd ~/my-project# Create a new virtual environmentpython3 -m venv .venv --prompt my-project# Activate the virtual environmentsource .venv/bin/activate# Update pippython -m pip install -U pipThen install pip-tools into the project&aposs virtual environment using pip:
python -m pip install pip-toolspip-tools through pipx, it is not yet well supported. The docs officially recommend installing pip-tools into your project&aposs environment, and I can confirm that this is the more reliable method.Your project&aposs dependencies go in a file called requirements.in. For example, the requirements.in file for a Django 3 project might look like this:
# ~/my-project/requirements.indjango<4.0You can generate a requirements.txt with fully resolved dependencies using the pip-compile command:
pip-compile --allow-unsafe --resolver=backtracking requirements.in--allow-unsafe and --resolver=backtracking options will both become the default in the next major release of pip-tools. The docs recommend passing these options to adopt the new default behavior.The requirements.txt file generated by pip-compile will look something like this:
## This file is autogenerated by pip-compile with Python 3.11# by the following command:## pip-compile --allow-unsafe --resolver=backtracking requirements.in#asgiref==3.6.0 # via djangodjango==3.2.16 # via -r requirements.inpytz==2022.7.1 # via djangosqlparse==0.4.3 # via djangoNotice that there is a comment at the top of the file indicating that it was autogenerated by pip-compile (it even includes the command!) and that every version number is pinned.
I usually create a second file called dev-requirements.in for development dependencies, such as pytest and django-debug-toolbar, and even pip-tools itself:
# ~/my-project/dev-requirements.in# Use requrements.txt as a constraint file-c requirements.txtdjango-debug-toolbarpip-toolspytestUsing requirements.txt as a constraint file ensures that any dependencies installed for the packages in dev-requirements.in are compatible with the package versions specified in requirements.txt.
Run pip-compile a second time to generate a dev-requirements.txt file:
pip-compile --allow-unsafe --resolver=backtracking dev-requirements.inNow for the real magic. Run pip-sync to synchronize your virtual environment with the packages in the requirements.txt and dev-requirements.txt files:
pip-sync requirements.txt dev-requirements.txtTo update or add a package, edit the appropriate .in file and then re-compile and re-sync everything.
-requirements.in and -requirements.txt files into version control.I often wrap all of this into a Makefile:
install:@pip install -r requirements.txt -r dev-requirements.txtcompile:@pip-compile --allow-unsafe --resolver=backtracking requirements.in@pip-compile --allow-unsafe --resolver=backtracking dev-requirements.insync:@pip-sync requirements.txt dev-requirements.txtCollaborators can run make install after cloning the repository to set up their environment, then run make compile && make sync as needed to keep everything synchronized.
Python dependency management tools abound.
I know many Python devs that swear by poetry or pipenv. And I know plenty that still use good ol&apos pip freeze. Personally, pipenv and poetry are too heavy-handed for my taste. pip freeze feels tedious to me. And the new pdm project looks interesting but still has a long way to go.
Call me Goldilocks, but pip-tools is the porridge that&aposs just right.
pipx Apps To ConsiderDepending on the kind of development you do, the following packages may be useful tools to install as applications with pipx:
cookiecutter for scaffolding projects.pre-commit for managing pre-commit hooks.tox for testing and task automation.build frontend for building Python packages.If you write and distribute Python packages, then you need to read Dan Hillard&aposs book Publishing Python Packages.
In addition to covering how to set up, publish, maintain, and scale your package, Dane discusses setting up a professional development environment specifically for package development. It is far more versatile than the environment described in this guide.
Get instant access from Manning, or buy a print version from Amazon.

One email, every Saturday, with one actionable tip.
Always less than 5 minutes of your time.