python-dev について
python-devは、Python開発者向けのコーディング規約スキルです。スタイル、型、例外処理、テスト、性能に加え、ツールやプロジェクト構成も扱います。
主な機能
- 01Blackとisortの利用指針
- 02命名と型注釈の規約
- 03例外処理とログの実践
- 04pytestと非同期処理の例
- 05構成と依存関係の指針
- 06性能改善の提案
活用シーン
- 01Pythonプロジェクトの書式統一
- 02型検査とインポート整理の計画
- 03テスト、非同期処理、依存管理の指針
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ doccker/ cc-use-exp --skill python-devインストール後、Claude Code で/python-devを入力して読み込まれたか確認します。
詳細
Python 開発規約
参考資料:PEP 8、Google Python Style Guide
ツールチェーン
# 格式化
black . # 代码格式化
isort . # import 排序
# 类型检查
mypy . # 静态类型检查
pyright . # 备选
# 代码检查
ruff check . # 快速 linter(推荐)
flake8 . # 传统 linter
# 测试
pytest -v # 运行测试
pytest --cov=src # 覆盖率
命名規則
| 種類 | 規則 | 例 |
|---|---|---|
| モジュール/パッケージ | 小文字とアンダースコア | user_service.py |
| クラス名 | アッパーキャメルケース | UserService, HttpClient |
| 関数/変数 | 小文字とアンダースコア | get_user_by_id, user_name |
| 定数 | 大文字とアンダースコア | MAX_RETRY_COUNT |
| プライベート | 先頭にアンダースコアを付ける | _internal_method |
型注釈
from typing import Optional, List, Dict, Union
from dataclasses import dataclass
@dataclass
class User:
id: int
name: str
email: Optional[str] = None
def find_user_by_id(user_id: int) -> Optional[User]:
"""根据 ID 查找用户"""
...
def process_items(items: List[str]) -> Dict[str, int]:
"""处理项目列表"""
return {item: len(item) for item in items}
# Python 3.10+ 可用新语法
def greet(name: str | None = None) -> str:
return f"Hello, {name or 'World'}"
例外処理
# ✅ 好:捕获具体异常
try:
user = repository.find_by_id(user_id)
except DatabaseError as e:
logger.error(f"Failed to find user {user_id}: {e}")
raise ServiceError(f"Database error: {e}") from e
# ✅ 好:上下文管理器
with open("file.txt", "r") as f:
content = f.read()
# ❌ 差:裸 except
try:
do_something()
except: # 永远不要这样做
pass
カスタム例外
class ServiceError(Exception):
"""服务层异常基类"""
def __init__(self, message: str, code: str = "UNKNOWN"):
super().__init__(message)
self.code = code
class UserNotFoundError(ServiceError):
"""用户不存在"""
def __init__(self, user_id: int):
super().__init__(f"User {user_id} not found", "USER_NOT_FOUND")
self.user_id = user_id
ログの規約
import logging
logger = logging.getLogger(__name__)
# ✅ 好:使用参数化日志
logger.debug("Finding user by id: %s", user_id)
logger.info("User %s logged in successfully", username)
logger.error("Failed to process order %s", order_id, exc_info=True)
# ❌ 差:f-string(即使不输出也会计算)
logger.debug(f"Finding user by id: {user_id}")
テストの規約(pytest)
import pytest
from unittest.mock import Mock, patch
class TestUserService:
@pytest.fixture
def user_service(self):
repository = Mock()
return UserService(repository)
def test_find_by_id_returns_user(self, user_service):
# given
expected = User(id=1, name="test")
user_service.repository.find_by_id.return_value = expected
# when
result = user_service.find_by_id(1)
# then
assert result == expected
user_service.repository.find_by_id.assert_called_once_with(1)
def test_find_by_id_raises_when_not_found(self, user_service):
# given
user_service.repository.find_by_id.return_value = None
# when/then
with pytest.raises(UserNotFoundError):
user_service.find_by_id(999)
# 参数化测试
@pytest.mark.parametrize("input,expected", [
(1, 1),
(2, 4),
(3, 9),
])
def test_square(input, expected):
assert square(input) == expected
非同期プログラミング
import asyncio
from typing import List
async def fetch_user(user_id: int) -> User:
"""异步获取用户"""
async with aiohttp.ClientSession() as session:
async with session.get(f"/api/users/{user_id}") as response:
data = await response.json()
return User(**data)
async def fetch_all_users(user_ids: List[int]) -> List[User]:
"""并发获取多个用户"""
tasks = [fetch_user(uid) for uid in user_ids]
return await asyncio.gather(*tasks)
# 限制并发数
async def fetch_with_limit(user_ids: List[int], limit: int = 10) -> List[User]:
semaphore = asyncio.Semaphore(limit)
async def fetch_one(uid: int) -> User:
async with semaphore:
return await fetch_user(uid)
return await asyncio.gather(*[fetch_one(uid) for uid in user_ids])
プロジェクト構成
project/
├── src/
│ └── myproject/
│ ├── __init__.py
│ ├── models/
│ ├── services/
│ ├── repositories/
│ └── utils/
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ └── test_*.py
├── pyproject.toml
├── requirements.txt
└── README.md
依存関係の管理
# pyproject.toml (推荐)
[project]
name = "myproject"
version = "1.0.0"
dependencies = [
"fastapi>=0.100.0",
"sqlalchemy>=2.0.0",
]
[project.optional-dependencies]
dev = [
"pytest>=7.0.0",
"black>=23.0.0",
"mypy>=1.0.0",
]
パフォーマンスの最適化
| 場面 | 方法 |
|---|---|
| 大規模データの処理 | ジェネレーター yield を使用する |
| 文字列の連結 | ''.join() を使用する |
| 検索処理 | set または dict を使用する |
| 並行 I/O | asyncio を使用する |
| CPU 負荷の高い処理 | multiprocessing を使用する |
# ✅ 使用生成器
def read_large_file(file_path: str):
with open(file_path, 'r') as f:
for line in f:
yield line.strip()
# ✅ 高效字符串拼接
result = ''.join(strings) # 而不是 += 循环
📋 この回答は次の規約に従っています:
python-dev- [具体的な章]
コメント
Markdown 対応