Virtual environments: one project, its own packages
A virtual environment is a folder with its own site-packages, so each project installs the versions it needs without fighting the others. You create and activate it in a terminal; from Python you can inspect it.
- Say what
python -m venv .venv, activation andpython -m pip installeach do, and where packages end up - Read the settings in a
pyvenv.cfgfile and turn them into a dictionary - Tell from
sys.prefixandsys.base_prefixwhether a program runs inside a virtual environment
Two projects on one computer rarely agree. The sales report needs pandas 2.2; an old invoice script only works with 1.5. If both install into the one Python that came with the computer, the second install replaces the first and one project breaks.
A virtual environment solves this with a folder. It has its own site-packages (where installed packages live), a bin/ folder (Scripts\ on Windows) with a python that uses that site-packages, and a small settings file, pyvenv.cfg, saying which Python it was made from. The commands, typed in a terminal on your own computer:
python -m venv .venvcreates the folder.venvnext to your project;source .venv/bin/activate(macOS, Linux) or.venv\Scripts\activate(Windows) activates it: for that terminal only,pythonandpipnow mean the ones inside.venv;python -m pip install pandasinstalls into whichever environment thatpythonbelongs to;deactivategoes back to the computer's own Python.
The Python in this page runs inside your browser, with no terminal and no pip, so these commands aren't run here. What a program *can* do anywhere is read the files an environment is made of, and ask its own interpreter where it lives. That's what the examples do.
Run each example to see what it prints. Running examples doesn't count toward progress.
cfg_text = """home = /usr/local/bin include-system-site-packages = false version = 3.12.4 executable = /usr/local/bin/python3.12 command = /usr/local/bin/python3.12 -m venv /home/ana/market-reports/.venv """ settings = {} for line in cfg_text.splitlines(): if "=" not in line: continue key, value = line.split("=", 1) settings[key.strip()] = value.strip() print(settings["version"]) print(settings["include-system-site-packages"]) print(len(settings), "settings")
A running program can also check whether it is inside an environment. sys.base_prefix is the folder of the Python installation; sys.prefix is the environment's folder when one is active and the same folder otherwise. So sys.prefix != sys.base_prefix means *inside a virtual environment*.
Where pip puts a package follows a fixed layout, and pathlib's pure paths can build it for either operating system without touching the disk: PurePosixPath joins with /, PureWindowsPath with \.
import sys from pathlib import PurePosixPath, PureWindowsPath def in_virtualenv(prefix, base_prefix): return prefix != base_prefix def site_packages(env_dir, version, windows): if windows: return PureWindowsPath(env_dir) / "Lib" / "site-packages" major_minor = ".".join(version.split(".")[:2]) return PurePosixPath(env_dir) / "lib" / f"python{major_minor}" / "site-packages" print(in_virtualenv("/home/ana/market-reports/.venv", "/usr/local")) print(in_virtualenv(sys.prefix, sys.base_prefix)) print(site_packages("/home/ana/market-reports/.venv", "3.12.4", False)) print(site_packages(r"C:\Users\ana\market-reports\.venv", "3.12.4", True))
When to use one: always, one environment per project. Make it once, activate it whenever you work on the project, and install with python -m pip so the pip you run belongs to the Python you mean.
Mistakes to avoid: running pip install in a terminal where the environment isn't active (the package lands in another Python, and import in your project still fails); committing .venv to git (it is big and machine-specific: list your dependencies instead, next lessons); and treating the text false in pyvenv.cfg as if it were False. Any non-empty text is true in an if.
- A virtual environment is a folder with its own site-packages and a
pyvenv.cfgsaying which Python made it. python -m venv .venv, activate, thenpython -m pip install …: activation only affects that terminal.sys.prefix != sys.base_prefixis true inside an environment; values inpyvenv.cfgare always text.- Next:
pyproject.toml, the file that describes the project itself and the packages it needs.