Python 环境与工具链

发布于 2026/07/08 | 深入理解 Python

本篇整理 Python 环境与工具链:解释器、标准库、第三方包、命令行入口、虚拟环境、pipuv


前面的文章关注语言机制和标准库接口。最后一篇回到工程入口:一段 Python 代码最终由哪个解释器运行、从哪里导入模块、包安装到哪里、命令行工具绑定到哪个环境。

1. 环境组成

一个可运行的 Python 环境由解释器、标准库、模块搜索路径、第三方包和脚本入口组成。运行同一段代码时,先确定“哪个解释器启动”,再确定“从哪些路径导入模块”,最后才是包管理工具如何把依赖写入对应环境。

对象典型位置或变量作用
解释器sys.executable执行 Python 字节码,决定运行时版本
环境前缀sys.prefix定位当前环境的库目录和脚本目录
基础 Pythonsys.base_prefix记录虚拟环境背后的基础 Python 安装
模块搜索路径sys.path决定 import 从哪里查找模块
标准库lib/pythonX.Y跟随 Python 版本提供内置模块
第三方包site-packages保存由 pip / uv 安装的包
可执行脚本.venv/bin / .venv\Scripts保存 pytestruff 等命令行入口

1.1 解释器

一个 Python 版本包含 python 可执行文件、标准库和支撑文件。命令行里运行的 pythonpython3python3.12 首先是一个解释器入口,它决定当前进程使用哪套运行时。

python
import sysprint(sys.executable.endswith('python') or 'python' in sys.executable) # Trueprint(sys.version_info.major >= 3) # True

常见路径:

对象含义
sys.executable当前 Python 进程对应的解释器可执行文件
sys.prefix当前环境前缀;在虚拟环境中指向虚拟环境目录
sys.base_prefix创建当前环境所用的基础 Python 前缀
sys.path模块搜索路径
site-packages第三方包安装目录

虚拟环境中 sys.prefix != sys.base_prefix;系统环境中二者通常相等。

python
import sysprint(isinstance(sys.path, list)) # Trueprint(sys.prefix == sys.base_prefix or sys.prefix != sys.base_prefix) # True

1.2 标准库

标准库随 Python 版本安装,提供 pathlibjsonasynciovenv 等模块。它不通过项目内的 pip install 单独安装;升级标准库通常意味着更换 Python 解释器版本。

python
import jsonimport pathlibprint(json.__name__)              # jsonprint(pathlib.Path('.').exists()) # True

标准库在 sys.path 中通常对应几类路径:

路径类型说明
pythonXY.zip标准库的压缩包入口;存在与否取决于具体安装方式
lib/pythonX.Y标准库 Python 源码目录
lib/pythonX.Y/lib-dynload标准库 C 扩展二进制模块目录

导入模块时,解释器按 sys.path 顺序从前到后搜索。解释器启动时会把几类路径放入 sys.path

来源说明
脚本目录或当前目录脚本运行时通常是脚本所在目录;交互式环境里常用空字符串表示当前目录
PYTHONPATH环境变量指定的搜索路径,会在解释器启动时加入 sys.path
标准库目录Python 自带模块所在目录
第三方包目录虚拟环境或系统环境中的 site-packages
.pth 文件追加的目录site 初始化时读取,常由安装工具或开发模式安装写入

例如:

bash
(pythonrelearn) qianshuang@qianshuangdeMacBook-Air PythonRelearn % export PYTHONPATH="Test" && echo "import sysfor path in sys.path:    print(path)" > main.py && uv run main.py /Users/qianshuang/Project/PythonProject/PythonRelearn # 当前工作目录/Users/qianshuang/Project/PythonProject/PythonRelearn/Test # PYTHONPATH 环境变量指定的目录/Users/qianshuang/.local/share/uv/python/cpython-3.14.3-macos-aarch64-none/lib/python314.zip # 标准库的压缩包版本/Users/qianshuang/.local/share/uv/python/cpython-3.14.3-macos-aarch64-none/lib/python3.14 # 标准库 Python 源码/Users/qianshuang/.local/share/uv/python/cpython-3.14.3-macos-aarch64-none/lib/python3.14/lib-dynload # 标准库的 C 扩展二进制模块/Users/qianshuang/Project/PythonProject/PythonRelearn/.venv/lib/python3.14/site-packages # 虚拟环境中的第三方包目录

1.3 第三方包

第三方包来自 PyPI、私有索引、本地 wheel 或源码目录,由 pipuv 等工具安装到当前环境的 site-packages

包管理工具安装分发包(distribution package),代码里导入导入包(import package)。两者名称经常相同,但分别属于安装层和导入层。例如有的分发包会提供多个导入包,也有的导入名与分发名不同。

第三方包除了提供可导入模块,还可能安装命令行脚本。脚本通常被放到当前环境的脚本目录中:

平台脚本目录
macOS / Linux.venv/bin
Windows.venv\Scripts

安装 ruffpytestblack 这类工具后,命令行能直接执行 ruffpytest,是因为使用虚拟环境时,激活脚本会把虚拟环境的脚本目录放到 PATH 前面,从而优先命中当前项目的工具版本。

可执行脚本的入口通常来自 pyproject.toml[project.scripts]

toml
[project.scripts]spam-cli = "spam:main"

安装该项目后,环境里会出现 spam-cli 命令;执行它时会导入 spam 模块并调用 main

2. 命令行

2.1 执行入口

Python 命令行的基本形态是:

bash
python [options] [script | -m module-name] [args]

常见入口:

写法作用sys.argv[0]
python进入交互模式''
python script.py执行文件脚本路径
python -m package.module按导入机制定位模块,并作为 __main__ 执行模块文件路径

script.py-m package.module 的差异主要在模块定位方式。直接执行文件时,脚本所在目录会进入 sys.path-m 先按导入机制查找模块,再把该模块作为顶层模块运行。

脚本或模块入口后的参数会进入 sys.argv[1:],由应用代码自行解析。

2.2 常用选项

日常更常用的是这些选项:

选项作用
-V / --version输出版本号
-VV输出更详细的构建信息
-m module按模块名执行
-c command执行字符串代码
-i执行脚本后进入交互模式
bash
python -V # Python 3.x.x

2.3 模块入口

python -m 是工具链中最重要的命令行习惯。它把“使用哪个解释器”和“执行哪个工具模块”绑定在一起。

bash
python -m pip --versionpython -m venv .venvpython -m http.server 8000python -m unittest

直接运行 pip install ... 时,命中的 pip 来自当前 PATH;运行 python -m pip install ... 时,pip 明确来自这个 python 解释器所在的环境。多 Python 版本共存时,后者更不容易装错环境。

模块入口和上一篇的模块知识是同一件事:python -m package 会执行 package.__main__python -m package.module 会把对应模块作为 __main__ 执行。

3. 虚拟环境

虚拟环境(virtual environment)把一个项目的第三方包、脚本入口和解释器前缀隔离出来。它的隔离范围限于 Python 环境目录。当前 Python 进程会优先使用该环境目录下的解释器、脚本和 site-packages

3.1 目录结构

标准库 venv 创建虚拟环境:

bash
python -m venv .venv

典型结构:

txt
.venv/├── pyvenv.cfg├── bin/              # Windows 为 Scripts/└── lib/pythonX.Y/site-packages/

核心文件与目录:

路径作用
pyvenv.cfg记录基础 Python 位置和是否包含系统 site-packages
bin/python / Scripts\python.exe虚拟环境解释器入口,通常是复制或符号链接
bin/pip / Scripts\pip.exe当前环境的 pip 入口
site-packages当前环境安装的第三方包

创建虚拟环境时,除非指定 --without-pipvenv 会通过 ensurepip 在环境中引导安装 pip

3.2 激活脚本

激活虚拟环境的作用范围是当前 shell。激活脚本主要修改 PATH 和提示符,让命令行优先找到 .venv 中的 pythonpip 和脚本。

bash
source .venv/bin/activate      # macOS / Linux.venv\Scripts\Activate.ps1     # Windows PowerShell

不激活也可以直接使用虚拟环境解释器:

bash
.venv/bin/python -m pip install requests.venv/bin/python script.py

这种写法在脚本、CI 和文档中更稳定,因为它不依赖当前 shell 是否已经激活环境。

3.3 环境重建

虚拟环境是可重建产物,不应提交到仓库。项目应该提交依赖声明和锁定结果,而非提交 .venv

文件作用是否通常提交
.venv/本地虚拟环境目录
requirements.txtpip 依赖输入或冻结结果
constraints.txt约束依赖版本,但不触发安装
pyproject.toml项目元数据、依赖、工具配置
uv.lockuv 锁定的完整解析结果应用项目通常提交

普通脚本项目可以用 requirements.txt 重建;现代项目更适合用 pyproject.toml 声明依赖,再用锁文件固定解析结果。

4. pip

pip 是 Python 生态最基础的包安装器。它负责从索引、本地文件、wheel 或源码目录安装分发包,并把包文件、元数据和脚本入口写入当前环境。

4.1 解释器绑定

优先使用 python -m pip

bash
python -m pip install requestspython -m pip listpython -m pip show requestspython -m pip uninstall requests

这样写能确保包安装到当前 python 对应的环境。多版本共存时,下面两条命令可能指向不同环境:

bash
pip install requestspython -m pip install requests

安装目标也可以是本地 wheel、源码目录、带 extras 的包或版本约束:

bash
python -m pip install "aiohttp[speedups]"python -m pip install "django>=5,<6"python -m pip install ./dist/example-0.1.0-py3-none-any.whl

4.2 依赖文件

requirements.txt 本质上是一组 pip install 参数。它可以手写直接依赖,也可以保存某个环境的完整冻结结果。

txt
requests==2.32.5aiohttp>=3.12,<4

按依赖文件安装:

bash
python -m pip install -r requirements.txt

pip freeze 输出当前环境中已安装分发包的版本固定结果,格式可直接交给 pip install -r

bash
python -m pip freezepython -m pip freeze > requirements.lock.txtpython -m pip install -r requirements.lock.txt

freeze 记录的是环境快照。它会把直接依赖和传递依赖一起列出。例如项目只主动安装 requests,冻结结果中还会出现 urllib3certifi 等由 requests 引入的包:

txt
certifi==2026.6.1charset-normalizer==3.4.4idna==3.11requests==2.32.5urllib3==2.5.0

freeze 的适用场景:

场景用法
保存脚本或应用当前可运行环境python -m pip freeze > requirements.lock.txt
复现一次问题现场提交或附带 freeze 输出,便于重建相同包版本
从旧项目迁移先 freeze 当前环境,再逐步整理直接依赖

freeze 的限制:

限制影响
不区分直接依赖和传递依赖很难看出项目主动依赖了哪些包
不表达 Python 版本要求需要另用 requires-python、文档或运行环境声明
不表达构建系统和项目元数据发布项目仍应使用 pyproject.toml
会记录当前环境状态环境中临时安装的调试包也可能进入输出

因此,应用项目可以提交锁定结果以重建部署环境;库项目应在 pyproject.toml 中声明兼容范围,让使用方在自己的依赖图中解析。

constraints.txt 只限制版本,不主动触发安装:

bash
python -m pip install -r requirements.txt -c constraints.txt

例如 requirements.txtrequestsconstraints.txturllib3<3,安装时会安装 requests,并把它依赖的 urllib3 限制在 <3 范围内。

4.3 项目元数据

现代 Python 项目通常用 pyproject.toml 描述项目。承载构建系统、项目元数据和工具配置。

toml
[build-system]requires = ["hatchling >= 1.26"]build-backend = "hatchling.build"[project]name = "example"version = "0.1.0"requires-python = ">=3.12"dependencies = [  "requests>=2.32",][project.optional-dependencies]dev = [  "pytest",  "ruff",]

关键表:

作用
[build-system]声明构建后端和构建依赖
[project]声明项目名称、版本、Python 版本要求、运行依赖
[project.optional-dependencies]声明 extras,例如 example[dev]
[project.scripts]声明安装后生成的命令行入口
[tool.xxx]放置工具私有配置,例如 ruffmypypytest

requirements.txt 记录安装清单;pyproject.toml 记录项目声明。应用项目通常还需要锁文件固定解析结果;库项目通常声明兼容范围,让使用方在自己的环境中解析。

5. uv

5.1 工具定位

uv 是用 Rust 编写的 Python 包与项目管理工具。它把多个工具链角色合并到一个 CLI 中:Python 版本管理、虚拟环境、pip 兼容安装、项目依赖、锁文件、脚本运行和命令行工具安装。

它有两条主线:

主线命令适用对象
pip 兼容工作流uv venvuv pip installuv pip freezeuv pip sync已有 requirements.txt 项目
项目工作流uv inituv adduv lockuv syncuv run使用 pyproject.tomluv.lock 的项目

5.2 Python 版本命令

uv 可以发现系统已有 Python,也可以安装 uv 管理的 Python。项目可以通过 .python-version 文件固定默认版本。

bash
uv python listuv python install 3.12uv python pin 3.12uv venv --python 3.12

.python-version 记录版本请求,虚拟环境目录仍由 .venv/ 或其他环境目录保存:

txt
3.12

uv 在项目命令中还会读取 pyproject.tomlrequires-python。如果没有找到合适解释器,uv 可以按需要下载受管理的 Python 版本。

常用命令:

命令作用
uv python list列出可用或可安装的 Python 版本
uv python install 3.12安装 uv 管理的 Python 3.12
uv python pin 3.12在当前项目写入 .python-version
uv venv --python 3.12用指定 Python 创建虚拟环境

5.3 虚拟环境与 pip 兼容命令

已有 requirements.txt 项目可以先用 pip 兼容模式:

bash
uv venvuv pip install -r requirements.txtuv pip install ruff

uv 默认会查找当前目录或父目录中的 .venv。如果已经激活其他虚拟环境,它也会识别 VIRTUAL_ENV

pip 兼容命令不要求项目存在 pyproject.toml

命令作用
uv venv创建 .venv 虚拟环境
uv venv --python 3.12指定 Python 版本创建虚拟环境
uv pip install requests向当前环境安装包
uv pip install -r requirements.txt按依赖文件安装
uv pip freeze以 requirements 格式列出当前环境包版本
uv pip sync requirements.txt将环境同步到依赖文件描述的结果

uv pip sync 适合把环境修正到文件指定状态。临时调试包如果不在依赖文件中,下一次 sync 会被移除。

5.4 项目命令

新项目可以使用项目模式:

bash
uv init example-appcd example-appuv add requestsuv run python main.pyuv lockuv sync

项目命令围绕 pyproject.tomluv.lock.venv/ 工作:

命令作用常用选项
uv init [PATH]创建新项目--app--lib--package--bare
uv add requests添加运行依赖--dev--optional--group--editable
uv remove requests删除依赖可指定普通依赖或依赖组
uv sync按锁文件同步 .venv/--locked--frozen--inexact
uv run python main.py在项目环境中运行命令--with--group--no-sync

uv add 会修改 pyproject.toml 中的依赖声明,并更新 uv.lock。默认情况下,它还会同步环境;使用 --no-sync 可以只改项目文件。

依赖可以按用途写入不同位置:

写法写入位置适用场景
uv add requests[project].dependencies运行时依赖
uv add pytest --dev开发依赖组测试、格式化、类型检查工具
uv add rich --optional cli[project.optional-dependencies].cliextras 依赖
uv add -r requirements.txt项目依赖声明从旧依赖文件迁移

5.5 锁文件

uv.lock 记录完整解析结果:包版本、来源、依赖关系、环境标记和校验信息。它服务于项目环境重建,避免每次安装都重新选择依赖版本。

核心文件:

文件作用是否提交
pyproject.toml项目元数据和直接依赖声明
uv.lock完整解析结果,用于可重复同步应用项目通常提交
.python-version默认 Python 版本请求通常提交
.venv/本地环境目录

锁文件相关命令:

命令作用
uv lock解析依赖并更新 uv.lock
uv lock --check检查 uv.lock 是否已经是最新状态
uv syncuv.lock 同步项目环境
uv sync --locked要求锁文件保持不变
uv sync --frozen使用现有锁文件同步环境
uv sync --inexact同步依赖时保留环境中的额外包

uv sync 默认按锁文件做精确同步,会移除锁文件之外的包。CI 和容器构建适合使用 uv sync --lockeduv sync --frozen; 本地临时实验可以使用 uv runuv sync --inexact

5.6 运行命令

uv run 在项目环境中执行命令。执行前,uv 会检查项目依赖并准备环境;命令结束后,环境保留在 .venv/ 中。

bash
uv run python main.pyuv run -m pytestuv run --with rich python script.py

常用写法:

写法作用
uv run python main.py用项目环境运行脚本
uv run -m pytest用项目环境运行模块
uv run --with rich python script.py临时带上额外包运行脚本
uv run --locked ...运行前要求锁文件保持不变
uvx ruff --version一次性运行命令行工具

6. 工作流选择

工具链选择应先看项目形态:

场景推荐工作流
单文件脚本,只用标准库直接 python script.py
小脚本需要少量第三方包python -m venv .venv + python -m pip install -r requirements.txt
已有 pip 项目继续 venv + python -m pip,或迁移到 uv venv + uv pip
新应用项目uv init + uv add + 提交 pyproject.tomluv.lock
发布库pyproject.toml 声明兼容范围,避免用应用锁文件约束使用方环境
CI / 容器明确 Python 版本,使用锁文件同步环境,不依赖交互式激活

Python 工具链的主线是:解释器决定运行时,虚拟环境决定安装位置,pip / uv 决定如何解析和写入依赖, pyproject.toml 与锁文件决定项目能否被稳定重建。