When you work in Python projects you probably should use a virtual environment (or a similar mechanism) to isolate the packages you install for each project.
Info
If you already know about virtual environments, how to create them and use them, you might want to skip this section. 🤓
Tip
A virtual environment is different than an environment variable.
An environment variable is a variable in the system that can be used by programs.
A virtual environment is a directory with some files in it.
Info
This page will teach you how to use virtual environments and how they work.
If you are ready to adopt a tool that manages everything for you (including installing Python), try uv.
What I normally do is that I create a directory named code inside my home/user directory.
And inside of that I create one directory per project.
fast →💬 Go to the home directorycd💬 Create a directory for all your code projectsmkdir code💬 Enter into that code directorycd code💬 Create a directory for this projectmkdir awesome-project💬 Enter into that project directorycd awesome-project restart ↻
Every time you install a new package in that environment, activate the environment again.
This makes sure that if you use a terminal (CLI) program installed by that package, you use the one from your virtual environment and not any other that could be installed globally, probably with a different version than what you need.
After you activated the virtual environment, you can run your program, and it will use the Python inside of your virtual environment with the packages you installed there.
You would probably use an editor, make sure you configure it to use the same virtual environment you created (it will probably autodetect it) so that you can get autocompletion and inline errors.
So, what's the problem with installing packages in the global Python environment?
At some point, you will probably end up writing many different programs that depend on different packages. And some of these projects you work on will depend on different versions of the same package. 😱
For example, you could create a project called philosophers-stone, this program depends on another package called harry, using the version 1. So, you need to install harry.
Then, at some point later, you create another project called prisoner-of-azkaban, and this project also depends on harry, but this project needs harry version 3.
But now the problem is, if you install the packages globally (in the global environment) instead of in a local virtual environment, you will have to choose which version of harry to install.
If you want to run philosophers-stone you will need to first install harry version 1, for example with:
And then you would end up with harry version 1 installed in your global Python environment.
But then if you want to run prisoner-of-azkaban, you will need to uninstall harry version 1 and install harry version 3 (or just installing version 3 would automatically uninstall version 1).
And then you would end up with harry version 3 installed in your global Python environment.
And if you try to run philosophers-stone again, there's a chance it would not work because it needs harry version 1.
Tip
It's very common in Python packages to try the best to avoid breaking changes in new versions, but it's better to be safe, and install newer versions intentionally and when you can run the tests to check everything is working correctly.
Now, imagine that with many other packages that all your projects depend on. That's very difficult to manage. And you would probably end up running some projects with some incompatible versions of the packages, and not knowing why something isn't working.
Also, depending on your operating system (e.g. Linux, Windows, macOS), it could have come with Python already installed. And in that case it probably had some packages pre-installed with some specific versions needed by your system. If you install packages in the global Python environment, you could end up breaking some of the programs that came with your operating system.
An important detail is that it will put the virtual environment path at the beginning of the PATH variable. The system will find it before finding any other Python available. This way, when you run python, it will use the Python from the virtual environment instead of any other python (for example, a python from a global environment).
Activating a virtual environment also changes a couple of other things, but this is one of the most important things it does.
That means that the python program that will be used is the one in the virtual environment.
You use which in Linux and macOS and Get-Command in Windows PowerShell.
The way that command works is that it will go and check in the PATH environment variable, going through each path in order, looking for the program called python. Once it finds it, it will show you the path to that program.
The most important part is that when you call python, that is the exact "python" that will be executed.
So, you can confirm if you are in the correct virtual environment.
Tip
It's easy to activate one virtual environment, get one Python, and then go to another project.
And the second project wouldn't work because you are using the incorrect Python, from a virtual environment for another project.
It's useful being able to check what python is being used. 🤓
If you don't deactivate the virtual environment for philosophers-stone, when you run python in the terminal, it will try to use the Python from philosophers-stone.
fast →cd ~/code/prisoner-of-azkaban python main.py 💬 Error importing sirius, it's not installed 😱Traceback (most recent call last): File "main.py", line 1, in import sirius
But if you deactivate the virtual environment and activate the new one for prisoner-of-askaban then when you run python it will use the Python from the virtual environment in prisoner-of-azkaban.
fast →cd ~/code/prisoner-of-azkaban 💬 You don't need to be in the old directory to deactivate, you can do it wherever you are, even after going to the other project 😎deactivate 💬 Activate the virtual environment in prisoner-of-azkaban/.venv 🚀source .venv/bin/activate 💬 Now when you run python, it will find the package sirius installed in this virtual environment ✨python main.py I solemnly swear 🐺
This is a simple guide to get you started and teach you how everything works underneath.
There are many alternatives to managing virtual environments, package dependencies (requirements), projects.
Once you are ready and want to use a tool to manage the entire project, packages dependencies, virtual environments, etc. I would suggest you try uv.
uv can do a lot of things, it can:
Install Python for you, including different versions
Manage the virtual environment for your projects
Install packages
Manage package dependencies and versions for your project
Make sure you have an exact set of packages and versions to install, including their dependencies, so that you can be sure that you can run your project in production exactly the same as in your computer while developing, this is called locking
If you read and understood all this, now you know much more about virtual environments than many developers out there. 🤓
Knowing these details will most probably be useful in a future time when you are debugging something that seems complex, but you will know how it all works underneath. 😎