1. Python 项目开发规范
1. Python 项目开发概述
Python 版本
本文仅考虑 Python3,不会考虑 Python2 项目,也不包括 Python 3.5 以前的古老版本。
Python 是一种高级编程语言,它的设计哲学强调代码的可读性和简洁的语法。Python 是一种解释型语言,它的解释器可以在多种操作系统上运行,包括 Windows、macOS 和各种形式的 Unix 系统。
当需要调用机器学习等模型时,Python 是首选的开发语言。Python 也广泛适用于服务器脚本开发、Web 开发、数据分析和客户端开发等领域。
但一直以来,Python 的项目一直没有严格的规范,导致了项目的混乱。为了解决这个问题,我们制定了一套 Python 项目开发规范。
选择 Python 版本时,不要使用最新的版本。推荐使用次新的版本或前两个版本,确保第三方库得到及时维护,当前推荐的版本为 3.11.11
。
安装 Python 的方法如下,Windows 10+:
winget install Python.Python.3.11
Ubuntu/Debian:
sudo apt install python3
CentOS/RHEL:
sudo yum install python3
macOS:
brew install python
brew install python@3.9
brew install python@3.10
brew install python@3.11
brew install python@3.12
brew install python@3.13
2. Python 开发基本规范
- 包和模块的命名必须符合 PEP8 规范
- 项目根目录下必须有
pyproject.toml
文件,用于管理项目依赖 - 项目如果需要分发,则必须提供
setup.py
文件 - 项目必须提供
requirements.txt
文件,且此文件的内容需要与pyproject.toml
文件中的一致 - 每个包下都必须有
__init__.py
文件,可以为空文件 - 源代码目录为包名,其名称尽量和关键字、标准库和第三方库的名称不同
- 当使用 monorepo 结构时,项目根目录下可以创建多个子项目
示例目录如下:
docs/
:文档目录resources/
:资源目录project_name/
common/
:通用模块constants/
:常量模块enums/
:枚举模块exceptions/
:异常模块models/
:模型模块entities/
:实体模块
configs/
:配置文件decorators/
:装饰器模块plugins/
:插件模块services/
:服务模块utils/
:工具模块views/
:视图模块或控制器模块core.py
:核心入口代码__init__.py
包入口文件
.editorconfig
EditorConfig 配置文件.gitignore
Git 忽略文件tests/
:测试目录LICENSE
:许可证文件pyproject.toml
:Python 项目配置文件README.md
:项目说明文件requirements.txt
:依赖文件setup.py
:分发文件
3. 代码风格规范
所有的代码风格遵循 PEP8,以下内容均在此基础上进行补充。
- Python 代码一律缩进使用 4 个空格
- 在项目中优先使用绝对导入,避免使用相对导入
- 使用
r
前缀表示正则表达式,使用R
前缀表示原始字符串 - 作为类型使用的导入放在文件的最后,这样可以防止循环导入,相当于 TypeScript 中的
import type { ... } from ...
混合语言规范
特别地,对于使用 Qt 等 C/C++/Rust/Go/Java 库的 Python 项目,部分变量或函数的命名可以不遵循 PEP8,而使用对于项目的命名来提供一致性的接口。例如,对于 Qt 项目中,在 Python 下创建的槽函数、信号等的名称使用小驼峰命名。
对于元编程,我们需要避免使用一些危险的操作。
禁止反射源代码和字节码,也避免使用一切反射源代码和字节码的第三方库。
反射源代码操作在编译为字节码后无法执行,因为源代码已经不存在。同样也避免包括反射 __code__
对象,反射 co_code
等字节码对象,操作字节码可能触发解释器层面的问题或内存泄漏等问题,如修改字节码可能出现 Segmentation fault。
并且,反射源代码和字节码无法被 Nuitka 等工具打包为产品。例如 ORM 库 mayim
通过反射代码执行操作,在打包后不能工作。建议将反射操作替换为反射类型签名,类型签名在各种运行时下可用。
同时避免使用执行代码的函数,如 eval()
和 exec()
,除非用于测试环境,否则将产生各种安全问题,参见 Python Cookbook。compile()
本身也不够安全,需要避免使用。
4. 开发环境
Python 推荐使用 VS Code 或 PyCharm 作为开发工具,对于 VS Code 建议安装以下插件:
code --install-extension ms-python.python
code --install-extension ms-python.black-formatter
code --install-extension ms-python.isort
对于独立的项目,必须使用虚拟环境来管理,虚拟环境的文件夹名默认为 venv
,创建命令如下:
python -m venv venv
VSCode 配置
.vscode/settings.json
配置保存自动格式化策略:
{
"python.analysis.autoImportCompletions": true,
"python.analysis.typeCheckingMode": "basic",
"python.analysis.importFormat": "absolute",
"[python]": {
"editor.defaultFormatter": "ms-python.black-formatter",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
},
},
"isort.args": [
"--profile",
"black"
]
}
.vscode/extensions.json
配置推荐插件:
{
"recommendations": [
"ms-python.python",
"ms-python.isort",
"ms-python.black-formatter"
]
}
5. Docker 镜像选型和构建
拉取当前推荐的版本:
docker pull python:3.11.11
精简版本:
docker pull python:3.11.11-alpine3.20
构建使用的版本:
docker pull python:3.11.11-bookworm
发布版本:
docker pull python:3.11.11-slim-bookworm
Dockerfile 示例
下面提供一个 Dockerfile
样例,这是一个基于 Sanic 的 Web 项目。此样例使用了多阶段构建,第一阶段使用构建版本的镜像,仅安装 Cython,并使用 Cython 编译项目,可以起到保护项目源代码、提高项目运行速度的作用。第二阶段使用精简版本的镜像,并安装完整的项目依赖。
ARG PYTHON_VERSION=3.11.11
ARG PYPI_MIRROR_URL=https://pypi.org/simple
# build stage
FROM python:${PYTHON_VERSION}-bookworm as builder
ARG PYPI_MIRROR_URL
WORKDIR /app
COPY . ./
RUN pip -V && \
python -m pip install -i ${PYPI_MIRROR_URL} --upgrade pip && \
pip config set global.index-url ${PYPI_MIRROR_URL} && \
pip install Cython && \
python setup.py build_ext -b lib && \
mv poetry.lock lib/ && \
mv pyproject.toml lib/
# production stage
FROM python:${PYTHON_VERSION}-slim-bookworm
ARG PYPI_MIRROR_URL
WORKDIR /app
COPY --from=builder /app/lib /app
RUN pip -V && \
python -m pip install -i ${PYPI_MIRROR_URL} --upgrade pip && \
pip config set global.index-url ${PYPI_MIRROR_URL} && \
pip install poetry
RUN python -m venv venv && \
. venv/bin/activate && \
poetry install --only main --no-interaction --no-ansi
ENV PATH=$PATH:/app/venv/bin
EXPOSE 8080
CMD [ "sanic", "server:app", "--host=0.0.0.0", "--port=8080", "--fast" ]