副标题: 90%的人不知道,好的文档能让你的代码被更多人使用
痛点:为什么你的代码没人愿意用?
2025年某开源项目有1000+ star,但issue里全是"怎么用"的问题。问题出在哪?工程师没有编写足够的文档。
真相:文档不是可有可无,而是代码的一部分。
| 文档类型 | 目的 | 工具 |
| API文档 | 说明接口用法 | Sphinx、MkDocs |
| 用户指南 | 指导用户使用 | Markdown |
| 开发文档 | 指导贡献者 | Markdown |
| 代码注释 | 解释实现细节 | docstring |
一、docstring基础
1.1 Google风格
def calculate_discount(price: float, discount_rate: float) -> float:
"""计算折扣后的价格。
Args:
price: 原价,必须大于0
discount_rate: 折扣率,范围0-1
Returns:
折扣后的价格
Raises:
ValueError: 当price <= 0或discount_rate不在0-1范围时
Example:
>>> calculate_discount(100, 0.2)
80.0
"""
if price <= 0:
raise ValueError("价格必须大于0")
if not 0 <= discount_rate <= 1:
raise ValueError("折扣率必须在0-1之间")
return price * (1 - discount_rate)
1.2 NumPy风格
def find_maximum(array):
"""
找到数组中的最大值。
Parameters
----------
array : list or tuple
包含数值的序列
Returns
-------
float or int
数组中的最大值
Examples
--------
>>> find_maximum([1, 5, 3, 9, 2])
9
"""
return max(array)
1.3 reST风格(Sphinx默认)
def connect_database(host, port=5432, user=None, password=None):
"""连接到数据库。
:param host: 数据库主机地址
:type host: str
:param port: 端口号,默认5432
:type port: int
:param user: 用户名
:type user: str
:param password: 密码
:type password: str
:return: 数据库连接对象
:rtype: Connection
:raises ConnectionError: 连接失败时抛出
"""
pass
二、类型注解
2.1 基础类型注解
from typing import List, Dict, Optional, Tuple, Union, Any
基础类型
def greet(name: str) -> str:
return f"Hello, {name}"
容器类型
def process_items(items: List[int]) -> Dict[str, int]:
return {"count": len(items), "sum": sum(items)}
可选类型
def find_user(user_id: int) -> Optional[Dict[str, Any]]:
...
联合类型
def parse_value(value: Union[str, int, float]) -> float:
return float(value)
元组类型
def get_coordinates() -> Tuple[float, float]:
return (0.0, 0.0)
任意类型
def log_message(message: Any) -> None:
print(message)
2.2 自定义类型
from typing import TypeVar, Generic, Protocol
类型变量
T = TypeVar('T')
class Stack(Generic[T]):
def __init__(self) -> None:
self._items: List[T] = []
def push(self, item: T) -> None:
self._items.append(item)
def pop(self) -> T:
return self._items.pop()
协议(接口)
class Drawable(Protocol):
def draw(self) -> None:
...
def render(shape: Drawable) -> None:
shape.draw()
2.3 类型检查
# 安装mypy
pip install mypy
运行类型检查
mypy your_module.py
严格模式
mypy --strict your_module.py
三、Sphinx文档
3.1 安装与初始化
# 安装
pip install sphinx sphinx-rtd-theme
初始化
cd docs
sphinx-quickstart
回答提示问题
3.2 配置conf.py
# conf.py
project = 'my-package'
copyright = '2026, Your Name'
author = 'Your Name'
release = '1.0.0'
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.napoleon', # Google/NumPy风格docstring
'sphinx.ext.viewcode',
'sphinx.ext.githubpages',
]
html_theme = 'sphinx_rtd_theme'
html_static_path = ['_static']
3.3 生成文档
# 生成API文档
sphinx-apidoc -o docs/source ../src
构建HTML文档
make html
预览
cd build/html
python -m http.server 8000
3.4 文档结构
docs/
├── source/
│ ├── conf.py
│ ├── index.rst # 首页
│ ├── api.rst # API文档
│ ├── guide.rst # 使用指南
│ └── _static/ # 静态文件
├── Makefile
└── requirements.txt
.. index.rst
Welcome to my-package's documentation!
======================================
.. toctree::
:maxdepth: 2
:caption: Contents:
guide
api
changelog
Indices and tables
==================
-
●:ref:genindex-
●:ref:modindex-
●:ref:search-
四、MkDocs文档
4.1 安装与初始化
# 安装
pip install mkdocs mkdocs-material
初始化
mkdocs new my-package-docs
cd my-package-docs
配置 mkdocs.yml
site_name: my-package
theme:
name: material
palette:
primary: blue
accent: indigo
nav:
- Home: index.md
- Guide:
- Installation: guide/installation.md
- Usage: guide/usage.md
- API:
- Core: api/core.md
- Utils: api/utils.md
- Changelog: changelog.md
plugins:
- search
- mkdocstrings
4.2 编写文档
<!-- index.md -->
my-package
一个强大的Python工具库。
快速开始
bash
pip install my-package
python
hello()
from my_package import hello
4.3 构建与部署
# 预览
mkdocs serve
构建
mkdocs build
部署到GitHub Pages
mkdocs gh-deploy
五、代码注释规范
5.1 模块注释
"""
my_package - 一个Python工具库
这个包提供了常用的数据处理和工具函数。
Example:
>>> from my_package import utils
>>> utils.add(1, 2)
3
Attributes:
__version__ (str): 版本号
"""
__version__ = '1.0.0'
5.2 类注释
class Database:
"""数据库连接类。
提供数据库连接、查询、事务管理等功能。
Attributes:
host (str): 数据库主机
port (int): 端口号
connection (Connection): 连接对象
Example:
>>> db = Database(host='localhost', port=5432)
>>> db.connect()
>>> db.execute('SELECT * FROM users')
"""
def __init__(self, host: str, port: int = 5432):
"""初始化数据库连接。
Args:
host: 数据库主机地址
port: 端口号,默认5432
"""
self.host = host
self.port = port
self.connection = None
5.3 函数注释
def process_data(data: List[Dict]) -> List[Dict]:
"""处理数据。
对输入数据进行清洗、转换和验证。
Args:
data: 原始数据列表,每个元素是一个字典
Returns:
处理后的数据列表
Raises:
ValidationError: 数据验证失败时抛出
Note:
处理过程包括:
1. 去除空值
2. 类型转换
3. 数据验证
"""
pass
5.4 行内注释
# ✅ 好的行内注释
result = calculate(x) # 计算x的平方
❌ 不好的行内注释
result = calculate(x) # 调用calculate函数
❌ 不必要的注释
x = 1 # x等于1
六、README规范
6.1 README模板
# 项目名称
[
](https://pypi.org/project/my-package/)
[
](https://pypi.org/project/my-package/)
[
](LICENSE)
简短描述项目用途。
特性
安装
bash
pip install my-package
python
hello()
from my_package import hello
文档
完整文档请访问:[https://my-package.readthedocs.io](https://my-package.readthedocs.io)
示例
python
example = Example()
example.run()
from my_package import Example
bash
克隆仓库
git clone https://github.com/yourname/my-package.git
cd my-package
安装开发依赖
pip install -e ".[dev]"
运行测试
pytest
构建文档
cd docs && make html
贡献
欢迎提交Issue和Pull Request!
许可证
MIT License - 详见 [LICENSE](LICENSE) 文件。
6.2 badges说明
[](https://pypi.org/project/my-package/)
[
](https://pypi.org/project/my-package/)
[
](LICENSE)
[
](https://github.com/yourname/my-package/actions)
[
](https://codecov.io/gh/yourname/my-package)
[
](https://my-package.readthedocs.io/)
七、CHANGELOG规范
7.1 Keep a Changelog格式
# Changelog
所有重要变更将记录在此文件中。
格式基于 [Keep a Changelog](https://keepachangelog.com/zh-CN/1.0.0/)。
版本遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
[未发布]
新增
[1.0.0] - 2026-05-26
新增
-
●初始版本发布-
●支持基本数据处理功能-
●添加命令行工具-
变更
修复
删除
[0.1.0] - 2026-05-01
新增
7.2 变更类型
| 类型 | 说明 |
| Added | 新功能 |
| Changed | 现有功能变更 |
| Deprecated | 即将移除的功能 |
| Removed | 已移除的功能 |
| Fixed | 修复bug |
| Security | 安全修复 |
八、最佳实践
8.1 文档检查清单
| 检查项 | 标准 |
| README | 包含安装、使用、示例 |
| API文档 | 所有公共接口有docstring |
| 类型注解 | 函数参数和返回值有类型 |
| 示例代码 | 可运行且正确 |
| CHANGELOG | 记录重要变更 |
| 贡献指南 | 说明如何贡献 |
8.2 注释规范
# ✅ 好的注释
计算两个向量的点积
def dot_product(a, b):
...
✅ 好的docstring
def add(a: int, b: int) -> int:
"""返回两个整数的和。
Args:
a: 第一个整数
b: 第二个整数
Returns:
两个整数的和
"""
return a + b
❌ 不好的注释
a加b
def add(a, b):
...
❌ 不必要的注释
x = 1 # x等于1
常见坑自查清单
| 坑 | 现象 | 自查方法 | 修复方案 |
| 文档过时 | 与代码不符 | 定期更新 | 代码变更时更新文档 |
| 缺少示例 | 用户不会用 | 添加示例 | README加快速开始 |
| 类型缺失 | IDE无提示 | 添加注解 | 使用mypy检查 |
| docstring缺失 | API文档空白 | 补充docstring | 使用Sphinx自动生成 |
结语
关键洞察:
-
●docstring是代码的一部分-
●类型注解提高代码可读性-
●README是项目的门面-
●CHANGELOG记录项目历史-
互动
-
1.你用Sphinx还是MkDocs?-
2.Google风格还是NumPy风格?-
3.觉得写文档麻烦吗?-
版本: V1.0 | 2026-05-26 | Python工程化系列
📚 推荐阅读
📝 摘要:今天深入学习静态代码分析技术,这是安全审计的核心技能。从 Python AST 模块到检测模式设计,收获满满!
发布于 202603
01-Python 环境搭建与第一个脚本
发布于 202603
【优化】Python代码优化与调试技巧
发布于 202603
KEYWORDS
IL, Python, python, 函数, 变量
💡 如果你觉得这篇文章有帮助,请点个在看,分享给更多需要的人!
📝 关注我,获取更多实用干货~
🤝 有问题欢迎评论区留言交流!