Four concepts carry most of pip-based Python development. Knowing each one cleanly distinguishes you from someone who 'just runs pip install' and hopes.
Virtual environments (venv). A directory containing its own Python interpreter copy and its own site-packages. Activating it adjusts your shell's PATH so python and pip resolve inside the venv. Deactivating restores PATH. Each project gets its own venv; nothing leaks between them. The .venv directory should be gitignored (always recreatable).
requirements.txt. A flat text file listing packages, optionally with version constraints (requests==2.31.0, flask>=3.0). pip reads it with pip install -r requirements.txt. Crucially, requirements.txt is not a true lockfile — it doesn't capture transitive dep versions or content hashes. For real reproducibility you need pip-tools (which generates a fully-pinned requirements.txt from a smaller requirements.in) or you switch to uv's uv.lock.
Editable installs (pip install -e .). When developing a Python package, you want changes to source code to take effect immediately — no reinstall on every save. pip install -e . installs the package as a symlink-equivalent into the venv's site-packages. This is how every Python library is developed.
Limitations. Three pip limitations that bite real projects: no Python version management (you need pyenv to install multiple Python versions); slow installs (pip resolves and downloads serially; uv parallelizes); dirty uninstalls (uninstall a package, its deps stay — they accumulate over time). pip's design just doesn't address these.