Skip to content

Python 项目管理

掌握 Poetry 和 uv 包管理器,理解 Python 项目的依赖管理和虚拟环境

📖 学习目标

  • 理解 Python 包管理的发展历程
  • 掌握 poetry 项目管理工具
  • 学会使用 uv 包管理器
  • 理解虚拟环境的概念和使用
  • 掌握依赖版本管理
  • 学会使用 pyproject.toml 配置项目

预计学习时间:1-2 天
难度:⭐⭐

1. Python 包管理发展历程

1.1 传统方式:pip + requirements.txt

bash
# 安装包
pip install requests

# 列出已安装的包
pip list

# 导出依赖
pip freeze > requirements.txt

# 从文件安装
pip install -r requirements.txt

requirements.txt 示例

txt
requests==2.31.0
flask==3.0.0
pandas==2.1.0

问题

  • 没有真正的依赖解析(可能产生依赖冲突)
  • 无法区分直接依赖和间接依赖
  • 版本锁定不够精确
  • 无法管理开发依赖和生产依赖

1.2 现代方式:Poetry / uv

特性pipPoetryuv
依赖解析
锁文件✅ poetry.lock✅ uv.lock
依赖分组
虚拟环境手动自动自动
发布包需要 setuptools
性能中等极快 ⚡

2. Poetry 项目管理

2.1 安装 Poetry

bash
# macOS/Linux
curl -sSL https://install.python-poetry.org | python3 -

# 或使用 pip(不推荐)
pip install poetry

# 验证安装
poetry --version

# 配置(可选)
poetry config virtualenvs.in-project true  # 在项目目录创建 .venv

2.2 创建新项目

bash
# 创建新项目
poetry new my-project

# 项目结构
my-project/
├── my_project/
   └── __init__.py
├── tests/
   └── __init__.py
├── pyproject.toml
└── README.md

# 或者在现有项目初始化
cd existing-project
poetry init

2.3 pyproject.toml 详解

toml
[tool.poetry]
name = "my-project"
version = "0.1.0"
description = "My awesome project"
authors = ["Your Name <you@example.com>"]
readme = "README.md"
packages = [{include = "my_project"}]

[tool.poetry.dependencies]
# 主要依赖
python = "^3.11"  # Python 版本要求
requests = "^2.31.0"  # ^ 表示兼容版本
flask = "~3.0.0"      # ~ 表示不更新主版本号
pandas = ">=2.0.0,<3.0.0"  # 指定范围

# 可选依赖
numpy = {version = "^1.24.0", optional = true}

[tool.poetry.group.dev.dependencies]
# 开发依赖
pytest = "^7.4.0"
black = "^23.0.0"
mypy = "^1.5.0"

[tool.poetry.group.docs]
# 文档依赖(可选组)
optional = true
[tool.poetry.group.docs.dependencies]
sphinx = "^7.0.0"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

版本约束语法

  • ^2.31.0>=2.31.0, <3.0.0(推荐,保持主版本兼容)
  • ~2.31.0>=2.31.0, <2.32.0(只更新修订版本)
  • *:任意版本
  • ==2.31.0:精确版本
  • >=2.31.0:最低版本

2.4 管理依赖

bash
# 添加依赖
poetry add requests                # 添加到主依赖
poetry add pytest --group dev      # 添加到开发依赖
poetry add sphinx --group docs     # 添加到文档依赖

# 添加特定版本
poetry add "requests>=2.25.0,<3.0.0"
poetry add "flask^3.0.0"

# 更新依赖
poetry update                      # 更新所有依赖
poetry update requests             # 更新指定包

# 删除依赖
poetry remove requests

# 显示依赖树
poetry show --tree

# 显示过时的包
poetry show --outdated

2.5 虚拟环境管理

bash
# 创建虚拟环境
poetry install                     # 安装所有依赖(包括 dev)
poetry install --without dev       # 不安装 dev 依赖
poetry install --with docs         # 安装可选的 docs 依赖

# 激活虚拟环境
poetry shell

# 在虚拟环境中运行命令
poetry run python script.py
poetry run pytest
poetry run black .

# 查看虚拟环境信息
poetry env info

# 列出所有虚拟环境
poetry env list

# 删除虚拟环境
poetry env remove python3.11

2.6 锁文件(poetry.lock)

bash
# poetry.lock 文件
# - 锁定所有依赖的精确版本
# - 确保团队成员使用相同的版本
# - 应该提交到版本控制

# 生成/更新锁文件
poetry lock

# 只更新锁文件,不安装
poetry lock --no-update

# 根据锁文件安装(推荐)
poetry install

3. uv 包管理器

3.1 安装 uv

bash
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

# 验证安装
uv --version

3.2 uv 基本使用

bash
# 创建虚拟环境
uv venv

# 激活虚拟环境
source .venv/bin/activate  # Linux/Mac
.venv\Scripts\activate     # Windows

# 安装包
uv pip install requests
uv pip install -r requirements.txt

# 同步依赖(根据 pyproject.toml)
uv sync

# 添加依赖
uv add requests
uv add pytest --dev

# 运行命令
uv run python script.py
uv run pytest

# 速度对比
# pip:    约 30s
# poetry: 约 15s
# uv:     约 2s ⚡

3.3 uv vs Poetry

python
# pyproject.toml(uv 格式)
[project]
name = "my-project"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
    "requests>=2.31.0",
    "flask>=3.0.0",
]

[dependency-groups]
dev = [
    "pytest>=7.4.0",
    "black>=23.0.0",
]

[tool.uv]
dev-dependencies = [
    "pytest>=7.4.0",
]

何时选择 uv

  • ✅ 追求极致的安装速度
  • ✅ 大型项目with众多依赖
  • ✅ CI/CD 环境
  • ❌ 需要发布包到 PyPI(用 Poetry)

何时选择 Poetry

  • ✅ 需要发布 Python 包
  • ✅ 需要更成熟的生态
  • ✅ 项目不是特别大
  • ✅ 团队已经熟悉 Poetry

4. Dify 项目分析

4.1 Dify API pyproject.toml

bash
# 查看 Dify 的依赖管理
cd /Users/zhangjinhe/Documents/my/codes/dify/api
cat pyproject.toml
  • Python 版本:3.11+

Dify 最新版(1.9.2)

  • 迁移到 uv
  • Python 版本:3.11+
  • 使用 uv.lock 锁定依赖

4.2 依赖组织

toml
# Dify 的依赖分组策略

# 主依赖:运行时必需
[project.dependencies]
flask = "~3.1.0"
celery = "~5.5.0"
sqlalchemy = "~2.0.29"
# ...

# 存储相关(可选)
[dependency-groups]
storage = [
    "azure-storage-blob==12.26.0",
    "google-cloud-storage==2.16.0",
]

# 向量数据库(可选)
vdb = [
    "weaviate-client==4.17.0",
    "qdrant-client==1.9.0",
    "pymilvus~=2.5.0",
]

# 开发工具
dev = [
    "pytest~=8.3.2",
    "ruff~=0.14.0",
    "basedpyright~=1.31.0",
]

4.3 环境搭建实践

bash
# 1. Clone Dify
git clone https://github.com/langgenius/dify.git
cd dify/api

# 2. 创建虚拟环境(使用 uv)
uv venv

# 3. 激活虚拟环境
source .venv/bin/activate  # Linux/Mac

# 4. 安装依赖
uv sync  # 安装所有默认依赖组

# 5. 配置环境变量
cp .env.example .env
# 编辑 .env 文件

# 6. 初始化数据库
flask db upgrade

# 7. 运行开发服务器
flask run --host 0.0.0.0 --port 5001 --debug

5. 虚拟环境深入

5.1 为什么需要虚拟环境?

python
"""
问题场景:
- 项目 A 需要 requests==2.25.0
- 项目 B 需要 requests==2.31.0
- 系统只能安装一个版本

解决方案:虚拟环境
- 每个项目有独立的 Python 环境
- 依赖隔离,互不干扰
"""

# 对比 Node.js
"""
Node.js:
- 每个项目有 node_modules 目录
- 天然隔离

Python:
- 默认全局安装到系统
- 需要虚拟环境隔离
"""

5.2 虚拟环境工具对比

bash
# 1. venv(Python 内置,推荐新手)
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

# 2. virtualenv(功能更强)
pip install virtualenv
virtualenv venv
source venv/bin/activate

# 3. Poetry(自动管理)
poetry install  # 自动创建虚拟环境
poetry shell    # 激活

# 4. uv(最快)
uv venv
source .venv/bin/activate
uv sync

# 5. conda(适合数据科学)
conda create -n myenv python=3.11
conda activate myenv

5.3 虚拟环境最佳实践

bash
# 1. 虚拟环境目录命名
.venv          # Poetry/uv 默认(推荐)
venv           # 常见
env            # 也常见

# 2. 添加到 .gitignore
echo ".venv/" >> .gitignore
echo "venv/" >> .gitignore
echo "*.pyc" >> .gitignore
echo "__pycache__/" >> .gitignore

# 3. 文档化 Python 版本
echo "python_version = \"3.11\"" >> .python-version
# 或使用 pyenv
pyenv local 3.11.7

# 4. 依赖管理
# ✅ 使用 poetry.lock 或 uv.lock
# ✅ 提交到版本控制
# ❌ 不要提交 .venv/ 目录

6. Python 版本管理

6.1 pyenv 管理多个 Python 版本

bash
# 安装 pyenv
curl https://pyenv.run | bash

# 列出可安装的版本
pyenv install --list

# 安装特定版本
pyenv install 3.11.7
pyenv install 3.12.1

# 设置全局版本
pyenv global 3.11.7

# 设置项目版本
cd my-project
pyenv local 3.11.7  # 创建 .python-version 文件

# 查看已安装版本
pyenv versions

6.2 使用多个 Python 版本测试

bash
# tox:多版本测试工具
pip install tox

# tox.ini
[tox]
envlist = py311,py312

[testenv]
deps = pytest
commands = pytest tests/

# 运行测试
tox

7. 实践项目

项目 1:创建一个完整的 Python 项目

bash
# 1. 创建项目
poetry new my-api
cd my-api

# 2. 添加依赖
poetry add flask
poetry add flask-sqlalchemy
poetry add pydantic

# 3. 添加开发依赖
poetry add pytest --group dev
poetry add black --group dev
poetry add mypy --group dev

# 4. 创建项目结构
mkdir -p my_api/{routes,models,services}
touch my_api/{__init__,app,config}.py

# 5. 配置工具
cat > pyproject.toml << 'EOF'
[tool.black]
line-length = 100
target-version = ['py311']

[tool.mypy]
python_version = "3.11"
strict = true
EOF

# 6. 运行工具
poetry run black .
poetry run mypy my_api/
poetry run pytest

项目 2:迁移 requirements.txt 到 Poetry

bash
# 1. 在现有项目中初始化
poetry init

# 2. 从 requirements.txt 导入
cat requirements.txt | xargs poetry add

# 3. 分离开发依赖
# 编辑 requirements-dev.txt
cat requirements-dev.txt | xargs poetry add --group dev

# 4. 验证
poetry install
poetry run python -m pytest

项目 3:搭建 Dify 开发环境

bash
#!/bin/bash
# setup_dify_dev.sh

# 1. 设置 Python 版本
pyenv install 3.11.7
pyenv local 3.11.7

# 2. 安装 uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# 3. 克隆项目
git clone https://github.com/langgenius/dify.git
cd dify

# 4. 后端设置
cd api
uv venv
source .venv/bin/activate
uv sync

# 5. 配置环境变量
cp .env.example .env
# 编辑 .env

# 6. 初始化数据库
flask db upgrade

# 7. 前端设置(另一个终端)
cd ../web
pnpm install
pnpm dev

# 8. 启动后端
cd ../api
flask run --debug

8. 常见问题

8.1 依赖冲突

bash
# 问题:包 A 需要 requests==2.25, 包 B 需要 requests>=2.30
# 解决:使用依赖解析器(Poetry/uv)

# Poetry 会自动解决
poetry add package-a package-b

# 如果无法解决,查看冲突
poetry add package-a package-b --dry-run

# 手动指定版本
poetry add "requests>=2.30"

8.2 锁文件同步问题

bash
# 问题:poetry.lock 和 pyproject.toml 不同步

# 解决:更新锁文件
poetry lock --no-update

# 重新安装
poetry install

8.3 虚拟环境激活问题

bash
# 问题:激活虚拟环境后仍使用系统 Python

# 检查
which python
python --version

# 确保正确激活
source .venv/bin/activate  # 注意路径

# 或使用 poetry run
poetry run python script.py

9. 思考题

  1. Poetry 和 npm/pnpm 有什么相似之处?
  2. 为什么需要锁文件(poetry.lock / uv.lock)?
  3. 什么是依赖解析?为什么重要?
  4. Dify 为什么从 Poetry 迁移到 uv?
  5. 如何在 Docker 中使用 Poetry/uv?

10. 检查清单

  • [ ] 理解 Python 包管理的发展
  • [ ] 能够使用 Poetry 管理项目
  • [ ] 了解 uv 的优势和使用
  • [ ] 掌握虚拟环境的创建和使用
  • [ ] 能够读懂 pyproject.toml
  • [ ] 成功搭建 Dify 开发环境

11. 完成 01-基础篇

恭喜!完成了 Python 基础篇的所有内容。现在你应该能够:

  • ✅ 流畅编写 Python 代码
  • ✅ 使用 Python 高级特性
  • ✅ 编写异步程序
  • ✅ 管理 Python 项目

12. 下一步

继续学习:

13. 参考资源