Help us learn about your current experience with the documentation. Take the survey.

创建新的 Python 项目

创建新的 Python 仓库时,一些指导原则有助于保持代码标准化。

推荐的库

开发与测试

  • pytest: 用于编写和运行测试的主要测试框架。
  • pytest-cov: pytest 的测试覆盖率报告插件。
  • black: 一个固执己见的代码格式化工具,确保代码风格一致。
  • flake8: 用于风格强制执行的 Linter。
  • pylint: 用于错误检测和质量强化的全面 Linter。
  • mypy: 静态类型检查器。
  • isort: 用于排序导入的工具。

包管理器与构建系统

  • poetry: 现代化的打包和依赖管理工具。

常用工具

  • typer: 用于构建 CLI 应用程序的库。
  • python-dotenv: 环境变量管理。
  • pydantic: 使用 Python 类型注解进行数据验证和设置管理。
  • fastapi: 用于构建 API 的现代化、高性能 Web 框架。
  • structlog: 结构化日志库。
  • httpx: 异步且高性能的 HTTP 客户端。
  • rich: 用于富文本的终端格式化库。
  • sqlmodel: 直观且强大的 ORM。
  • tqdm: CLI 的快速、可扩展进度条。

推荐的文件夹结构

根据项目类型的不同,例如 API 服务、CLI 应用程序或库,文件夹结构可能会有所不同。以下结构是标准的 CLI 应用程序。

project_name/
├── .gitlab/                     # GitLab 特定配置
│   ├── issue_templates/         # Issue 模板
│   └── merge_request_templates/ # MR 模板
├── .gitlab-ci.yml               # CI/CD 配置
├── project_name/                # 主包目录
│   ├── __init__.py              # 包初始化
│   ├── cli.py                   # 命令行接口入口点
│   ├── config.py                # 配置处理
│   └── core/                    # 核心功能
│       └── __init__.py
├── tests/                       # 测试目录
│   ├── __init__.py
│   ├── conftest.py              # pytest fixtures 和配置
│   └── test_*.py                # 测试模块
├── docs/                        # 文档
├── scripts/                     # 实用脚本
├── README.md                    # 项目概述
├── CONTRIBUTING.md              # 贡献指南
├── LICENSE                      # 许可信息
├── pyproject.toml               # 项目元数据和依赖(Poetry)

Linter 配置

我们应该尽可能将配置整合到 pyproject.toml 中。

pyproject.toml

[tool.black]
line-length = 120

[tool.isort]
profile = "black"

[tool.mypy]
python_version = 3.12
ignore_missing_imports = true

[tool.pylint.main]
jobs = 0
load-plugins = [
  # 自定义插件
]

[tool.pylint.messages_control]
enable = [
  # 自定义插件
]

[tool.pylint.reports]
score = "no"

setup.cfg

[flake8]
extend-ignore = E203,E501
extend-exclude = **/__init__.py,.venv,tests
indent-size = 4
max-line-length = 120

示例 Makefile

# 项目 Makefile 节选,显示常用目标

# lint
.PHONY: install-lint-deps
install-lint-deps:
    @echo "安装 lint 依赖..."
    @poetry install --only lint

.PHONY: format
format: black isort

.PHONY: black
black: install-lint-deps
    @echo "运行 black 格式化..."
    @poetry run black ${CI_PROJECT_DIR}

.PHONY: isort
isort: install-lint-deps
    @echo "运行 isort 格式化..."
    @poetry run isort ${CI_PROJECT_DIR}

.PHONY: lint
lint: flake8 check-black check-isort check-pylint check-mypy

.PHONY: flake8
flake8: install-lint-deps
    @echo "运行 flake8..."
    @poetry run flake8 ${CI_PROJECT_DIR}

.PHONY: check-black
check-black: install-lint-deps
    @echo "运行 black 检查..."
    @poetry run black --check ${CI_PROJECT_DIR}

.PHONY: check-isort
check-isort: install-lint-deps
    @echo "运行 isort 检查..."
    @poetry run isort --check-only ${CI_PROJECT_DIR}

.PHONY: check-pylint
check-pylint: install-lint-deps install-test-deps
    @echo "运行 pylint 检查..."
    @poetry run pylint ${CI_PROJECT_DIR}

.PHONY: check-mypy
check-mypy: install-lint-deps
    @echo "运行 mypy 检查..."
    @poetry run mypy ${CI_PROJECT_DIR}

# test
.PHONY: test
test: install-test-deps
    @echo "运行测试..."
    @poetry run pytest

.PHONY: test-coverage
test-coverage: install-test-deps
    @echo "运行带覆盖率的测试..."
    @poetry run pytest --cov=duo_workflow_service --cov=lints --cov-report term --cov-report html

示例 GitLab CI 配置

# .gitlab-ci.yml 节选,显示 linting 和测试任务

image: python:3.13

stages:
  - lint
  - test

variables:
  PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
  POETRY_CACHE_DIR: "$CI_PROJECT_DIR/.cache/poetry"
  POETRY_VERSION: "2.1.2"

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - $PIP_CACHE_DIR
    - $POETRY_CACHE_DIR
    - .venv/

# Python 任务的基础模板
.poetry:
  before_script:
    - pip install poetry==${POETRY_VERSION}
    - poetry config virtualenvs.in-project true
    - poetry add --dev black isort flake8 pylint mypy pytest pytest-cov

# Linting 任务
black:
  extends: .poetry
  stage: lint
  script:
    - poetry run black --check ${CI_PROJECT_DIR}

isort:
  extends: .poetry
  stage: lint
  script:
    - poetry run isort --check-only ${CI_PROJECT_DIR}

flake8:
  extends: .poetry
  stage: lint
  script:
    - poetry run flake8 ${CI_PROJECT_DIR}

pylint:
  extends: .poetry
  stage: lint
  script:
    - poetry run pylint ${CI_PROJECT_DIR}

mypy:
  extends: .poetry
  stage: lint
  script:
    - poetry run mypy ${CI_PROJECT_DIR}

# 测试任务
test:
  extends: .poetry
  stage: test
  script:
    - poetry run pytest --cov=duo_workflow_service --cov-report=term --cov-report=xml:coverage.xml --junitxml=junit.xml
  coverage: '/TOTAL.+?(\d+\%)/'
  artifacts:
    when: always
    reports:
      junit: junit.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage.xml

添加审查者轮盘

我们推荐使用审查者轮盘来分配审查工作量给审查者和维护者。对于小型 Python 项目,有一个 Python 审查者池,可以按照这些步骤进行配置。

要创建特定于项目的审查者池:

  1. 按照 GitLab Dangerfiles 说明 将配置添加到您的项目中。

  2. 在您的 GitLab CI 管道中实现 Danger Reviewer 组件 以自动触发轮盘。