Skip to content

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+:

bash
winget install Python.Python.3.11

Ubuntu/Debian:

bash
sudo apt install python3

CentOS/RHEL:

bash
sudo yum install python3

macOS:

bash
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 Cookbookcompile() 本身也不够安全,需要避免使用。

4. 开发环境

Python 推荐使用 VS Code 或 PyCharm 作为开发工具,对于 VS Code 建议安装以下插件:

bash
code --install-extension ms-python.python
code --install-extension ms-python.black-formatter
code --install-extension ms-python.isort

对于独立的项目,必须使用虚拟环境来管理,虚拟环境的文件夹名默认为 venv,创建命令如下:

bash
python -m venv venv

VSCode 配置

.vscode/settings.json 配置保存自动格式化策略:

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 配置推荐插件:

json
{
  "recommendations": [
    "ms-python.python",
    "ms-python.isort",
    "ms-python.black-formatter"
  ]
}

5. Docker 镜像选型和构建

拉取当前推荐的版本:

bash
docker pull python:3.11.11

精简版本:

bash
docker pull python:3.11.11-alpine3.20

构建使用的版本:

bash
docker pull python:3.11.11-bookworm

发布版本:

bash
docker pull python:3.11.11-slim-bookworm

Dockerfile 示例

下面提供一个 Dockerfile 样例,这是一个基于 Sanic 的 Web 项目。此样例使用了多阶段构建,第一阶段使用构建版本的镜像,仅安装 Cython,并使用 Cython 编译项目,可以起到保护项目源代码、提高项目运行速度的作用。第二阶段使用精简版本的镜像,并安装完整的项目依赖。

dockerfile
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" ]