在现代 Python 开发中,创建可重用的包并在 IDE 中获得良好的开发体验是每个开发者都会遇到的需求。本文将通过一个实际案例,详细介绍如何从一个配置好的
pyproject.toml
文件开始,完成 Python 包的本地安装、版本管理,以及解决 PyCharm 中常见的导入警告和代码跳转问题。
理解 pyproject.toml 配置文件
什么是 pyproject.toml
pyproject.toml
是现代 Python 项目的标准配置文件,基于 PEP 518 和 PEP 621 规范。它统一了项目元数据、依赖关系和构建配置的管理方式。
实际案例分析
让我们以一个名为 deepagents
的项目为例,分析其 pyproject.toml
文件:
[project]
name = "deepagents"
version = "0.0.3"
description = "General purpose 'deep agent' with sub-agent spawning, todo list capabilities, and mock file system. Built on LangGraph."
readme = "README.md"
license = { text = "MIT" }
requires-python = ">=3.11,<4.0"
dependencies = [
"langgraph>=0.2.6",
"langchain-anthropic>=0.1.23",
"langchain>=0.2.14",
]
[build-system]
requires = ["setuptools>=73.0.0", "wheel"]
build-backend = "setuptools.build_meta"
[tool.setuptools]
packages = ["deepagents"]
[tool.setuptools.package-dir]
"deepagents" = "src/deepagents"
[tool.setuptools.package-data]
"*" = ["py.typed"]
配置详解
项目基本信息 ([project]
部分)
- name: 包名,用于 PyPI 发布和 pip 安装
- version: 版本号,遵循语义化版本控制
- description: 项目简短描述
- readme: 说明文档文件路径
- license: 开源许可证信息
- requires-python: Python 版本要求
- dependencies: 运行时依赖列表
构建系统配置 ([build-system]
部分)
- requires: 构建工具依赖
- build-backend: 指定构建后端
Setuptools 配置
- packages: 要包含的 Python 包
- package-dir: 包目录映射(src 布局)
- package-data: 额外包含的文件
项目结构特点
从配置可以看出这个项目的特点:
- 使用 src 布局: 源代码位于
src/deepagents
目录,这是推荐的项目结构 - 支持类型提示: 包含
py.typed
文件 - 专注于 AI/LLM 应用: 依赖 LangChain 生态系统
- 早期开发阶段: 版本号 0.0.3
Python 包的分发方式
中央仓库 vs 本地使用
发布到中央仓库
优势:
- 全球可访问性
- 版本管理
- 依赖解析
- 社区贡献
发布流程:
# 构建包
python -m build
# 上传到 TestPyPI(推荐先测试)
twine upload --repository testpypi dist/*
# 上传到正式 PyPI
twine upload dist/*
个人本地使用
对于个人项目或内部使用,本地安装更加灵活:
优势:
- 无需注册账户
- 快速迭代
- 隐私保护
- 完全控制
本地包安装详解
方式一:直接本地安装(推荐)
cd /path/to/deepagents
# 普通安装
pip install .
# 开发模式安装(推荐)
pip install -e .
开发模式安装的优势
使用 -e
参数(editable/可编辑安装)的好处:
- 实时更新: 修改源代码后无需重新安装
- 方便调试: 可以直接在源码中添加调试信息
- 保持同步: 代码更改立即生效
方式二:构建后安装
# 安装构建工具
pip install build
# 构建包
python -m build
# 安装构建好的包
pip install dist/deepagents-0.0.3-py3-none-any.whl
虚拟环境最佳实践
# 创建虚拟环境
python -m venv deepagents_env
# 激活虚拟环境
# Windows:
deepagents_env\Scripts\activate
# macOS/Linux:
source deepagents_env/bin/activate
# 在虚拟环境中安装
pip install -e .
版本信息集成
添加版本显示功能
在 src/deepagents/__init__.py
中添加:
__version__ = "0.0.3"
from deepagents.deep_agent import create_deep_agent
from deepagents.sub_agent import SubAgent
__all__ = ["create_deep_agent", "SubAgent", "__version__"]
在核心代码中使用版本信息
from deepagents.sub_agent import create_task_tool, SubAgent
from deepagents.model import get_default_model
from deepagents.tools import write_todos, write_file, read_file, ls, edit_file
from deepagents.state import DeepAgentState
from typing import Sequence, Union, Callable, Any, TypeVar, Type, Optional
from langchain_core.tools import BaseTool
from langchain_core.language_models import LanguageModelLike
from langgraph.prebuilt import create_react_agent
# 添加版本信息
__version__ = "0.0.3"
StateSchema = TypeVar("StateSchema", bound=DeepAgentState)
StateSchemaType = Type[StateSchema]
base_prompt = f"""You are DeepAgents v{__version__}. You have access to a number of standard tools
## `write_todos`
You have access to the `write_todos` tools to help you manage and plan tasks. Use these tools VERY frequently to ensure that you are tracking your tasks and giving the user visibility into your progress.
These tools are also EXTREMELY helpful for planning tasks, and for breaking down larger complex tasks into smaller steps. If you do not use this tool when planning, you may forget to do important tasks - and that is unacceptable.
It is critical that you mark todos as completed as soon as you are done with a task. Do not batch up multiple tasks before marking them as completed.
## `task`
- When doing web search, prefer to use the `task` tool in order to reduce context usage."""
def create_deep_agent(
tools: Sequence[Union[BaseTool, Callable, dict[str, Any]]],
instructions: str,
model: Optional[Union[str, LanguageModelLike]] = None,
subagents: list[SubAgent] = None,
state_schema: Optional[StateSchemaType] = None,
):
"""Create a deep agent.
This agent will by default have access to a tool to write todos (write_todos),
and then four file editing tools: write_file, ls, read_file, edit_file.
Args:
tools: The additional tools the agent should have access to.
instructions: The additional instructions the agent should have. Will go in
the system prompt.
model: The model to use.
subagents: The subagents to use. Each subagent should be a dictionary with the
following keys:
- `name`
- `description` (used by the main agent to decide whether to call the sub agent)
- `prompt` (used as the system prompt in the subagent)
- (optional) `tools`
state_schema: The schema of the deep agent. Should subclass from DeepAgentState
"""
prompt = instructions + base_prompt
built_in_tools = [write_todos, write_file, read_file, ls, edit_file]
if model is None:
model = get_default_model()
state_schema = state_schema or DeepAgentState
task_tool = create_task_tool(
list(tools) + built_in_tools,
instructions,
subagents or [],
model,
state_schema
)
all_tools = built_in_tools + list(tools) + [task_tool]
return create_react_agent(
model,
prompt=prompt,
tools=all_tools,
state_schema=state_schema,
)
def get_version():
"""获取 DeepAgents 版本信息"""
return __version__
使用示例
import deepagents
# 检查版本
print(deepagents.__version__) # 输出: 0.0.3
# 使用核心功能
agent = deepagents.create_deep_agent(
tools=[],
instructions="你是一个助手"
)
解决 PyCharm 中的导入问题
常见问题现象
即使包能正常运行,PyCharm 中可能出现:
- 导入语句有黄色波浪线警告
- 无法通过 Ctrl+Click 跳转到源代码
- 代码补全功能不工作
- 静态代码分析报错
根本原因分析
这些问题的根本原因是 PyCharm 无法正确识别包的结构或导入路径,特别是对于使用 src 布局的项目。
解决方案详解
方案一:配置 Sources Root(最重要)
这是解决问题的关键步骤:
- 在 PyCharm 中右键点击
src
目录 - 选择 Mark Directory as → Sources Root
- src 目录图标会变成蓝色文件夹,表示已正确标记
为什么这样有效:
- PyCharm 需要明确知道哪些目录包含源代码
- 标记后 PyCharm 能正确理解包结构
- 导入解析变得准确
方案二:使用开发模式安装
# 确保使用开发模式安装
pip uninstall deepagents
pip install -e .
验证安装结果:
python -c "import deepagents; print(deepagents.__file__)"
应该显示源代码路径而不是 site-packages 路径。
方案三:刷新 PyCharm 索引
清理缓存:
- File → Invalidate Caches and Restart
- 勾选所有选项并重启
重新同步解释器:
- File → Settings → Project → Python Interpreter
- 点击齿轮图标 → Show All
- 选择解释器 → Show paths → Reload list of paths
方案四:检查项目解释器
确保 PyCharm 使用了正确的 Python 解释器:
- File → Settings → Project → Python Interpreter
- 如果使用虚拟环境,确保选择了正确的虚拟环境解释器
方案五:配置项目结构
- File → Settings → Project → Project Structure
- 确保项目根目录是 Content Root
src
目录是 Sources Root- 可以将
dist
、build
等目录标记为 Excluded
验证解决效果
解决方案生效后,你应该能享受到:
✅ 无警告提示: 导入语句不再有黄色波浪线
✅ 代码跳转: Ctrl+Click 可以跳转到源代码
✅ 智能补全: 输入时显示可用的函数和类
✅ 代码检查: 正确的静态代码分析
✅ 重构支持: 重命名等操作能正确处理依赖
完整的开发工作流
1. 项目初始化
# 项目结构
deepagents/
├── src/
│ └── deepagents/
│ ├── __init__.py
│ ├── deep_agent.py
│ ├── sub_agent.py
│ ├── model.py
│ ├── tools.py
│ ├── state.py
│ └── py.typed
├── tests/
├── pyproject.toml
└── README.md
2. 配置 PyCharm
- 用 PyCharm 打开项目
- 标记
src
为 Sources Root - 配置 Python 解释器
3. 安装和测试
# 开发模式安装
pip install -e .
# 测试安装
python -c "import deepagents; print(deepagents.__version__)"
4. 验证 IDE 功能
# 测试文件
import deepagents
# 这里应该能够:
# - 看到代码补全
# - Ctrl+Click 跳转
# - 没有导入警告
agent = deepagents.create_deep_agent(
tools=[],
instructions="测试代理"
)
常见问题和解决方案
问题 1: 包能运行但 IDE 有警告
现象: 代码能正常执行,但 PyCharm 显示导入警告
解决: 标记 src
为 Sources Root + 清理缓存
问题 2: 无法跳转到源代码
现象: Ctrl+Click 不能跳转到定义
解决: 确保使用开发模式安装 + 配置 Sources Root
问题 3: 版本号不一致
现象: __init__.py
和 pyproject.toml
中版本号不同
解决: 保持两处版本号同步,或使用动态版本读取
问题 4: 包结构识别错误
现象: PyCharm 无法正确识别包结构
解决: 检查 __init__.py
文件,确保正确的导入语句
最佳实践总结
项目结构
- 使用 src 布局: 推荐的现代 Python 项目结构
- 标准化配置: 使用
pyproject.toml
统一管理 - 类型支持: 包含
py.typed
文件
开发环境
- 虚拟环境: 为每个项目创建独立环境
- 开发模式安装: 使用
pip install -e .
- IDE 配置: 正确标记 Sources Root
版本管理
- 统一版本号: 在
__init__.py
和pyproject.toml
中保持一致 - 语义化版本: 遵循 semver 规范
- 版本显示: 提供获取版本信息的接口
代码质量
- 类型提示: 使用类型注解提高代码质量
- 文档字符串: 完善的函数和类文档
- 测试覆盖: 编写充分的测试用例
结语
通过本文的详细介绍,我们完整地展示了从 pyproject.toml
配置到完美 IDE 体验的全过程。关键要点包括:
- 理解现代 Python 包配置:
pyproject.toml
是标准化的配置方式 - 选择合适的安装方式: 个人使用推荐本地开发模式安装
- 正确配置 IDE: 标记 Sources Root 是解决大部分问题的关键
- 建立完整工作流: 从项目结构到开发环境的全面配置
掌握这些技能将大大提升你的 Python 包开发效率和体验。无论是个人项目还是团队协作,这套完整的解决方案都能帮助你创建高质量、易维护的 Python 包。
现代 Python 开发不仅仅是写好代码,更重要的是建立高效的开发工作流。希望这篇详细的指南能帮助你在 Python 包开发的道路上走得更远、更稳。