
Your Python installation is shared by default. That feels convenient until one project needs an older package and another project needs a newer one. Install both globally and you have made the interpreter responsible for an argument it cannot resolve cleanly.
A virtual environment is a project-specific directory containing an interpreter and its installed packages. It lets each project choose its own dependencies without changing every other project on the machine. The environment is not a container and it does not install a second operating system. It is a boundary around Python packages.
That boundary does not make the source code portable by itself. You still need to record the packages and the Python version your project expects. The environment is disposable; the dependency description is the part you keep.
Python includes the venv module. Run this command from the project directory. It creates a directory named myenv:
python -m venv myenvActivate it with the command for your shell:
# Linux or macOS
source myenv/bin/activate
# Windows PowerShell
.\myenv\Scripts\Activate.ps1
# Windows Command Prompt
myenv\Scripts\activate.batAfter activation, your shell usually shows (myenv) in the prompt. More useful than the prompt is checking which interpreter is running:
python -c "import sys; print(sys.executable)"The printed path should point inside myenv. Commands such as python and pip now use the environment, so an install stays with this project.
I prefer python -m pip because it makes the connection between the Python interpreter and its package installer explicit:
python -m pip install requestsIf PowerShell blocks the activation script with an execution-policy error, that is a shell policy problem, not a broken Python environment. You can still run the environment's interpreter directly, or adjust the policy according to your machine's rules. Do not copy a policy command from a random post without understanding whether it changes the policy for only your user or for the whole machine.
When you finish working, leave the environment with:
# Deactivate the virtual environment
deactivateThe command only changes the current shell. It does not delete the environment or uninstall its packages. If you close the terminal, the environment directory remains on disk.
Do not commit the myenv directory to your repository. It contains machine-specific paths and can become large. Record the packages your project needs in requirements.txt instead:
python -m pip freeze > requirements.txtOn another machine, create and activate a fresh environment, then install those recorded versions:
python -m pip install -r requirements.txtOne honest caveat: pip freeze records everything installed in the environment, including packages you may have added while experimenting. For a small project that is often fine. For a long-lived project, review the file before committing it. A clean environment makes that review much easier.
Add the environment directory to .gitignore as well:
myenv/
.venv/
venv/The exact directory name is your choice. .venv is common too; consistency matters more than the name.
For a small tutorial, requirements.txt is enough. A package or a larger application may eventually use pyproject.toml to describe dependencies and build settings. The file format can change, but the workflow does not: a new machine should be able to create a clean environment from a short, reviewable declaration.
If the environment gets confused, recreate it instead of trying to repair every installed package by hand. First update the dependency file, remove the disposable environment directory, and run python -m venv again. The source code is outside that directory, so rebuilding it is normally the safer fix.
Create the environment once, activate it whenever you work on the project, install packages through python -m pip, and deactivate it when you are done. When a teammate checks out the project, they can recreate the environment from requirements.txt instead of receiving a copy of yours.
The routine is not glamorous, and it does not solve every deployment problem. It does solve the common mistake of installing a package into one interpreter and running the program with another. For Python projects, that is enough reason to make virtual environments your default.
