mcpField
P
python-package-management

python-package-management

github.com/josiahsiegel开发5971 次安装19 周前更新
代码仓库

关于 python-package-management

面向 Python 开发者的实用技能,涵盖项目创建、依赖管理、代码检查与包发布,并介绍 uv、Ruff 等工具。

主要功能

  1. 01使用 uv 创建项目并管理依赖
  2. 02同步环境并锁定依赖版本
  3. 03配置 pyproject.toml 和项目结构
  4. 04使用 Ruff 检查和格式化代码
  5. 05构建并发布包到 PyPI

适用场景

  1. 01使用 uv 启动 Python 项目
  2. 02保持项目依赖可复现
  3. 03配置代码检查与格式化
  4. 04准备向 PyPI 发布包

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill python-package-management

安装后在 Claude Code 中输入/python-package-management确认已加载。

详细介绍

快速参考

uv 命令用途
uv init my-project创建新项目
uv add <package>添加依赖
uv add --dev <package>添加开发依赖
uv sync安装所有依赖
uv run <command>在虚拟环境中运行
uv lock --upgrade更新所有依赖
uv python install 3.13安装 Python 版本
工具命令速度
uvuv add requests快 10-100 倍
pippip install requests基准
ruff 命令用途
ruff check .检查代码
ruff check --fix .自动修复问题
ruff format .格式化代码
项目布局推荐方案
src 布局src/my_package/
测试tests/
配置pyproject.toml

何时使用此技能

用于项目设置和依赖管理:

  • 启动新的 Python 项目
  • 配置 uv 以实现快速的包管理
  • 配置 pyproject.toml
  • 使用 ruff 设置代码检查
  • 将包发布到 PyPI

相关技能:

  • CI/CD:参见 python-github-actions
  • 测试:参见 python-testing
  • 类型提示配置:参见 python-type-hints

Python 包管理(2025)

概述

现代 Python 包管理以 uv(基于 Rust 的快速工具)、pip 和 pyproject.toml 为核心。本指南介绍依赖管理、虚拟环境和项目配置的最佳实践。

uv — 现代包管理器

为什么选择 uv?
  • 比 pip 快 10-100 倍(使用 Rust 编写)
  • 可替代 pip、pip-tools、pipx、poetry、pyenv、virtualenv
  • 自动管理虚拟环境
  • 支持锁定文件,确保可复现性
  • 创建虚拟环境快约 200 倍
安装
# macOS/Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
irm https://astral.sh/uv/install.ps1 | iex

# pip (works everywhere)
pip install uv

# Homebrew
brew install uv
快速入门
# Create new project
uv init my-project
cd my-project

# Add dependencies
uv add requests fastapi pydantic

# Add dev dependencies
uv add --dev pytest ruff mypy

# Sync environment (install all dependencies)
uv sync

# Run commands in the environment
uv run python main.py
uv run pytest
基本命令
# Package management
uv add <package>              # Add dependency
uv add <package>==1.0.0       # Specific version
uv add --dev <package>        # Dev dependency
uv remove <package>           # Remove dependency
uv sync                       # Sync environment with lockfile

# Virtual environments
uv venv                       # Create .venv
uv venv --python 3.12         # Specific Python version
uv venv my-env                # Named environment

# pip compatibility
uv pip install <package>      # Install (faster pip)
uv pip install -r requirements.txt
uv pip freeze > requirements.txt
uv pip compile pyproject.toml -o requirements.txt

# Python management
uv python install 3.13        # Install Python version
uv python list                # List installed versions
uv python pin 3.12            # Pin project Python version

# Running
uv run <command>              # Run in virtual env
uv run --with httpx python    # Run with temporary package
使用 uv 配置 pyproject.toml
[project]
name = "my-project"
version = "0.1.0"
description = "My Python project"
readme = "README.md"
requires-python = ">=3.11"
license = {text = "MIT"}
authors = [
    {name = "Your Name", email = "[email protected]"}
]
dependencies = [
    "fastapi>=0.100.0",
    "pydantic>=2.0.0",
    "httpx>=0.25.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0.0",
    "ruff>=0.1.0",
    "mypy>=1.8.0",
]

[project.scripts]
my-cli = "my_project.cli:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.uv]
dev-dependencies = [
    "pytest>=8.0.0",
    "ruff>=0.1.0",
    "mypy>=1.8.0",
]
uv.lock
# Lockfile is auto-generated and should be committed
# Contains exact versions for reproducibility

# Update all dependencies
uv lock --upgrade

# Update specific package
uv lock --upgrade-package requests

# Install from lockfile only
uv sync --frozen

项目结构

推荐:src 布局
my-project/
├── src/
│   └── my_package/
│       ├── __init__.py
│       ├── main.py
│       ├── models.py
│       └── utils/
│           ├── __init__.py
│           └── helpers.py
├── tests/
│   ├── __init__.py
│   ├── conftest.py
│   ├── test_main.py
│   └── test_models.py
├── docs/
│   └── index.md
├── pyproject.toml
├── uv.lock
├── README.md
├── LICENSE
└── .gitignore
为什么使用 src 布局?
  1. 避免导入混淆——不会意外从项目根目录导入
  2. 强制安装——必须安装包才能测试
  3. 分发内容更整洁——wheel 中只有包代码
  4. 语义清晰——代码、测试和文档明确分离
扁平布局(适用于更简单的项目)
my-project/
├── my_package/
│   ├── __init__.py
│   └── main.py
├── tests/
│   └── test_main.py
├── pyproject.toml
└── README.md

pyproject.toml 完整参考

[project]
name = "my-project"
version = "1.0.0"
description = "A comprehensive Python project"
readme = "README.md"
requires-python = ">=3.11"
license = {text = "MIT"}
keywords = ["python", "example", "package"]
classifiers = [
    "Development Status :: 4 - Beta",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: MIT License",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.11",
    "Programming Language :: Python :: 3.12",
    "Programming Language :: Python :: 3.13",
]
authors = [
    {name = "Your Name", email = "[email protected]"}
]
maintainers = [
    {name = "Maintainer", email = "[email protected]"}
]

dependencies = [
    "fastapi>=0.100.0",
    "pydantic>=2.0.0",
    "sqlalchemy>=2.0.0",
]

[project.optional-dependencies]
dev = [
    "pytest>=8.0.0",
    "pytest-cov>=4.0.0",
    "ruff>=0.1.0",
    "mypy>=1.8.0",
    "pre-commit>=3.0.0",
]
docs = [
    "mkdocs>=1.5.0",
    "mkdocs-material>=9.0.0",
]
all = ["my-project[dev,docs]"]

[project.scripts]
my-cli = "my_package.cli:main"

[project.entry-points."my_package.plugins"]
plugin1 = "my_package.plugins:Plugin1"

[project.urls]
Homepage = "https://github.com/user/my-project"
Documentation = "https://my-project.readthedocs.io"
Repository = "https://github.com/user/my-project"
Changelog = "https://github.com/user/my-project/blob/main/CHANGELOG.md"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/my_package"]

# Ruff configuration
[tool.ruff]
target-version = "py311"
line-length = 88
src = ["src", "tests"]

[tool.ruff.lint]
select = [
    "E",     # pycodestyle errors
    "W",     # pycodestyle warnings
    "F",     # Pyflakes
    "I",     # isort
    "B",     # flake8-bugbear
    "C4",    # flake8-comprehensions
    "UP",    # pyupgrade
    "ARG",   # flake8-unused-arguments
    "SIM",   # flake8-simplify
]
ignore = [
    "E501",  # line too long (handled by formatter)
]

[tool.ruff.lint.isort]
known-first-party = ["my_package"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"

# Mypy configuration
[tool.mypy]
python_version = "3.12"
strict = true
warn_return_any = true
warn_unused_ignores = true
disallow_untyped_defs = true
plugins = ["pydantic.mypy"]

[[tool.mypy.overrides]]
module = "tests.*"
disallow_untyped_defs = false

# Pytest configuration
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
addopts = [
    "-ra",
    "-q",
    "--strict-markers",
    "--cov=src/my_package",
    "--cov-report=term-missing",
]

# Coverage configuration
[tool.coverage.run]
branch = true
source = ["src/my_package"]
omit = ["*/tests/*", "*/__init__.py"]

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "def __repr__",
    "raise NotImplementedError",
    "if TYPE_CHECKING:",
]

Ruff — 代码检查与格式化

为什么选择 Ruff?
  • 比 Flake8 和 Black 合计快 10-100 倍
  • 使用单一工具进行代码检查和格式化
  • 内置 800 多条规则
  • 支持自动修复
  • 使用 Rust 编写(由 Astral 开发,与 uv 相同)
基本用法
# Linting
ruff check .                   # Check for issues
ruff check --fix .             # Auto-fix issues
ruff check --watch .           # Watch mode

# Formatting
ruff format .                  # Format all files
ruff format --check .          # Check formatting

# Both
ruff check --fix . && ruff format .
配置
# pyproject.toml
[tool.ruff]
target-version = "py311"
line-length = 88
src = ["src", "tests"]

[tool.ruff.lint]
select = [
    "E",      # pycodestyle errors
    "W",      # pycodestyle warnings
    "F",      # Pyflakes
    "I",      # isort
    "B",      # flake8-bugbear
    "C4",     # flake8-comprehensions
    "UP",     # pyupgrade
    "ARG",    # flake8-unused-arguments
    "SIM",    # flake8-simplify
    "TCH",    # flake8-type-checking
    "PTH",    # flake8-use-pathlib
    "ERA",    # eradicate (commented code)
    "PL",     # Pylint
    "PERF",   # Perflint
    "RUF",    # Ruff-specific rules
]
ignore = [
    "E501",   # line too long (handled by formatter)
    "PLR0913", # too many arguments
]

# Per-file ignores
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101"]  # Allow assert in tests
"__init__.py" = ["F401"]    # Allow unused imports

[tool.ruff.lint.isort]
known-first-party = ["my_package"]
force-single-line = true

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
Pre-commit 集成
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.4.0
    hooks:
      - id: ruff
        args: [--fix]
      - id: ruff-format

  - repo: https://github.com/pre-commit/mirrors-mypy
    rev: v1.9.0
    hooks:
      - id: mypy
        additional_dependencies:
          - pydantic
          - types-requests

pip 和 requirements.txt

何时使用 pip
  • 需要稳定性的生产环境
  • 旧项目
  • 不含复杂依赖的简单脚本
requirements.txt 最佳实践
# requirements.txt - Pinned versions for production
fastapi==0.109.0
pydantic==2.5.3
sqlalchemy==2.0.25
httpx==0.26.0

# requirements-dev.txt
-r requirements.txt
pytest==8.0.0
ruff==0.1.14
mypy==1.8.0
生成 requirements.txt
# From uv
uv pip compile pyproject.toml -o requirements.txt
uv pip compile pyproject.toml --extra dev -o requirements-dev.txt

# From pip-tools
pip-compile pyproject.toml -o requirements.txt
pip-compile pyproject.toml --extra dev -o requirements-dev.txt

# Freeze current environment (not recommended for reproducibility)
pip freeze > requirements.txt

虚拟环境最佳实践

位置
# Recommended: Project-local .venv
project/
├── .venv/        # Virtual environment here
├── src/
├── tests/
└── pyproject.toml

# uv creates .venv by default
uv venv

# Explicit location
uv venv .venv
python -m venv .venv
.gitignore
# Virtual environments
.venv/
venv/
ENV/
env/

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python

# Distribution
build/
dist/
*.egg-info/

# IDE
.idea/
.vscode/
*.swp
*.swo

# Testing
.pytest_cache/
.coverage
htmlcov/
.mypy_cache/

# Ruff
.ruff_cache/
激活(必要时)
# Usually not needed with uv - just use `uv run`

# Linux/macOS
source .venv/bin/activate

# Windows (PowerShell)
.venv\Scripts\Activate.ps1

# Windows (cmd)
.venv\Scripts\activate.bat

# Deactivate
deactivate

发布包

构建和发布
# Build with uv
uv build

# Publish to PyPI
uv publish

# Or with twine
pip install twine
twine upload dist/*

# Test PyPI first
twine upload --repository testpypi dist/*
版本管理
# pyproject.toml - dynamic version from __init__.py
[project]
dynamic = ["version"]

[tool.hatch.version]
path = "src/my_package/__init__.py"
# src/my_package/__init__.py
__version__ = "1.0.0"

评论

支持 Markdown