一、项目结构概述
良好的项目结构是代码可维护性和团队协作的基础。典型的Python项目遵循一定的组织规范。
# 典型Python项目结构
my_project/
├── README.md
├── LICENSE
├── setup.py
├── requirements.txt
├── .gitignore
├── src/
│ └── my_package/
│ ├── __init__.py
│ ├── module1.py
│ └── module2.py
├── tests/
│ ├── __init__.py
│ ├── test_module1.py
│ └── test_module2.py
└── docs/
├── index.md
└── guide.md
二、项目根目录文件
2.1 README.md
# Project Name
Brief description of the project.
## Installation
```bash
pip install project-name
Usage
from project_name import main
main.run()
Features
License
MIT
### 2.2 LICENSE
MIT License
Copyright (c) 2024 Your Name
Permission is hereby granted, free of charge...
### 2.3 setup.py
```python
from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as f:
long_description = f.read()
setup(
name="my-project",
version="0.1.0",
author="Your Name",
author_email="your.email@example.com",
description="A short description",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/username/my-project",
packages=find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.8",
install_requires=[
"requests>=2.28.0",
"numpy>=1.24.0",
],
extras_require={
"dev": ["pytest", "black", "flake8"],
"docs": ["sphinx", "sphinx-rtd-theme"],
},
entry_points={
"console_scripts": [
"my-cli=my_package.cli:main",
],
},
)
2.4 requirements.txt
# 核心依赖
requests==2.31.0
numpy==1.24.3
pandas==2.0.3
# 开发依赖
pytest==7.4.0
black==23.7.0
flake8==6.0.0
mypy==1.4.0
2.5 requirements-dev.txt
-r requirements.txt
# 开发工具
pytest==7.4.0
pytest-cov==4.1.0
black==23.7.0
flake8==6.0.0
mypy==1.4.0
isort==5.12.0
pre-commit==3.3.3
2.6 .gitignore
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# Virtual environments
venv/
env/
ENV/
.venv
# IDE
.vscode/
.idea/
*.swp
*.swo
# Testing
.pytest_cache/
.coverage
htmlcov/
.tox/
# Build
build/
dist/
*.egg-info/
# Jupyter
.ipynb_checkpoints/
# Logs
*.log
# Environment variables
.env
.env.local
# OS
.DS_Store
Thumbs.db
三、源代码目录
3.1 src布局
src/
└── my_package/
├── __init__.py
├── __version__.py
├── cli.py
├── core/
│ ├── __init__.py
│ ├── models.py
│ └── services.py
├── utils/
│ ├── __init__.py
│ ├── helpers.py
│ └── validators.py
└── data/
├── __init__.py
└── schemas.py
3.2 init.py
"""
My Package - A brief description.
"""
from .core.models import User, Product
from .core.services import UserService
from .utils.helpers import format_date
__version__ = "0.1.0"
__all__ = ["User", "Product", "UserService", "format_date"]
3.3 version.py
"""Version information."""
__version__ = "0.1.0"
__author__ = "Your Name"
__email__ = "your.email@example.com"
四、测试目录
4.1 测试结构
tests/
├── __init__.py
├── conftest.py
├── unit/
│ ├── __init__.py
│ ├── test_models.py
│ └── test_services.py
├── integration/
│ ├── __init__.py
│ └── test_api.py
└── fixtures/
├── sample_data.json
└── config.yaml
4.2 conftest.py
import pytest
from my_package.core.models import User
@pytest.fixture
defsample_user():
"""Create a sample user for testing."""
return User(
id=1,
name="Test User",
email="test@example.com"
)
@pytest.fixture
defsample_users():
"""Create multiple sample users."""
return [
User(id=1, name="User1", email="user1@example.com"),
User(id=2, name="User2", email="user2@example.com"),
]
defpytest_configure(config):
"""Configure pytest."""
config.addinivalue_line(
"markers", "slow: mark test as slow"
)
4.3 test_models.py
import pytest
from my_package.core.models import User
classTestUser:
"""Test User model."""
deftest_user_creation(self):
"""Test user creation."""
user = User(id=1, name="John", email="john@example.com")
assert user.id == 1
assert user.name == "John"
assert user.email == "john@example.com"
deftest_user_str(self):
"""Test string representation."""
user = User(id=1, name="John", email="john@example.com")
assertstr(user) == "User(id=1, name=John)"
@pytest.mark.slow
deftest_user_validation(self):
"""Test user validation."""
pass
五、文档目录
5.1 文档结构
docs/
├── index.md
├── installation.md
├── usage.md
├── api/
│ ├── index.md
│ └── core.md
├── examples/
│ ├── basic.py
│ └── advanced.py
└── _build/
5.2 index.md
# My Project Documentation
Welcome to the documentation for My Project.
## Quick Start
```bash
pip install my-project
python -c "import my_package"
Contents
Contributing
Please see Contributing Guide
---
## 六、配置文件
### 6.1 pyproject.toml
```toml
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"
[tool.black]
line-length = 100
target-version = ['py39', 'py310']
[tool.isort]
profile = "black"
line_length = 100
[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_functions = ["test_*"]
markers = [
"slow: marks tests as slow",
]
[tool.mypy]
python_version = "3.9"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
6.2 .flake8
[flake8]
max-line-length = 100
ignore = E501, W503, E203
exclude = .git,__pycache__,venv,.env
statistics = True
count = True
6.3 .pre-commit-config.yaml
repos:
-repo:https://github.com/pre-commit/pre-commit-hooks
rev:v4.4.0
hooks:
-id:trailing-whitespace
-id:end-of-file-fixer
-id:check-yaml
-id:check-added-large-files
-repo:https://github.com/psf/black
rev:23.7.0
hooks:
-id:black
language_version:python3
-repo:https://github.com/PyCQA/isort
rev:5.12.0
hooks:
-id:isort
args: ["--profile=black"]
-repo:https://github.com/PyCQA/flake8
rev:6.1.0
hooks:
-id:flake8
args: ["--max-line-length=100"]
七、CI/CD配置
7.1 GitHub Actions
# .github/workflows/ci.yml
name:CI
on: [push, pull_request]
jobs:
test:
runs-on:ubuntu-latest
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
-uses:actions/checkout@v3
-name:SetupPython
uses:actions/setup-python@v4
with:
python-version:${{matrix.python-version}}
-name:Installdependencies
run:|
python -m pip install --upgrade pip
pip install -e .[dev]
-name:Lint
run:|
flake8 src/
black --check src/
isort --check-only src/
-name:Test
run:|
pytest --cov=src/ --cov-report=xml
-name:Uploadcoverage
uses:codecov/codecov-action@v3
with:
file:./coverage.xml
八、脚本和工具
8.1 Makefile
.PHONY: help install test lint format clean
help:
@echo "Available commands:"
@echo " install Install the package"
@echo " test Run tests"
@echo " lint Run linters"
@echo " format Format code"
@echo " clean Clean build artifacts"
install:
pip install -e .[dev]
test:
pytest tests/
lint:
flake8 src/
black --check src/
format:
black src/
isort src/
clean:
rm -rf build/
rm -rf dist/
rm -rf *.egg-info
find . -type d -name __pycache__ -delete
find . -type f -name "*.pyc" -delete
8.2 入口脚本
# cli.py
import argparse
import sys
defmain():
"""Main entry point."""
parser = argparse.ArgumentParser(
description="My Project CLI"
)
parser.add_argument(
"--version",
action="version",
version="%(prog)s 0.1.0"
)
parser.add_argument(
"command",
choices=["run", "test", "clean"],
help="Command to execute"
)
args = parser.parse_args()
if args.command == "run":
print("Running...")
elif args.command == "test":
print("Testing...")
elif args.command == "clean":
print("Cleaning...")
if __name__ == "__main__":
main()
九、常见问题
9.1 导入问题
# ✅ 使用绝对导入
from my_package.core.models import User
from my_package.utils.helpers import format_date
# ❌ 避免相对导入
from .core.models import User # 不推荐
9.2 循环导入
# ✅ 使用延迟导入
defget_user_service():
from my_package.core.services import UserService
return UserService()
# ✅ 重构代码
# core/models.py
# core/services.py
# 避免相互依赖
十、总结
# 快速参考
# 项目结构
my_project/
├── README.md
├── LICENSE
├── setup.py
├── requirements.txt
├── .gitignore
├── pyproject.toml
├── src/
│ └── package/
├── tests/
├── docs/
└── .github/
└── workflows/
# 配置文件
.pyproject.toml # 现代Python配置
.setup.cfg # 传统配置
.flake8 # flake8配置
.pre-commit-config.yaml # pre-commit配置
# 关键文件
__init__.py # 包初始化
__version__.py # 版本信息
conftest.py # pytest配置
良好的项目结构是Python开发的基础。遵循标准结构可以让代码更容易维护、测试和部署。推荐使用src布局,将源代码与测试和配置分开。使用pyproject.toml统一管理配置。通过CI/CD和pre-commit钩子自动化质量检查。记住"结构清晰的项目是成功的一半"。