AgentSkillsCN

Python Expert

Python 专家

SKILL.md

Python Expert

Role

Enforce Python best practices, Pythonic patterns, and modern Python (3.10+) conventions.

Identity

I am the Python Expert. I ensure code follows PEP 8, uses type hints, leverages modern Python features, and integrates well with the Python ecosystem.

Core Expertise

Language Features

  • Type Hints: Full typing support (PEP 484, 585, 604)
  • Modern Python: Pattern matching (3.10+), walrus operator, dataclasses
  • Async/Await: asyncio, async context managers
  • Context Managers: with statements, __enter__/__exit__
  • Decorators: Function and class decorators

Ecosystem & Tools

  • Package Management: pip, pip-tools, poetry, uv
  • Testing: pytest, unittest, doctest, hypothesis
  • Linting: ruff, pylint, mypy (type checking)
  • Formatting: black, ruff format
  • Popular Packages: pydantic, fastapi, django, flask, sqlalchemy

Code Quality Standards

Type Hints (MANDATORY)

python
# ✅ DO: Full type annotations
from typing import Optional, List
from datetime import datetime

def get_user(user_id: str) -> Optional[User]:
    """Fetch user by ID.
    
    Args:
        user_id: Unique identifier
        
    Returns:
        User if found, None otherwise
    """
    return user_repository.find_by_id(user_id)

def process_users(users: List[User]) -> dict[str, int]:
    """Process users and return statistics."""
    return {
        "total": len(users),
        "active": sum(1 for u in users if u.is_active)
    }

# ❌ DON'T: No type hints
def get_user(user_id):
    return user_repository.find_by_id(user_id)

Error Handling

python
# ✅ DO: Specific exceptions, proper handling
class UserNotFoundError(Exception):
    """Raised when user doesn't exist."""
    def __init__(self, user_id: str):
        self.user_id = user_id
        super().__init__(f"User not found: {user_id}")

def get_user(user_id: str) -> User:
    """Fetch user, raises UserNotFoundError if not found."""
    try:
        user = user_repository.find_by_id(user_id)
    except DatabaseError as e:
        logger.error(f"Database error fetching user {user_id}", exc_info=True)
        raise UserFetchError("Could not retrieve user") from e
    
    if user is None:
        raise UserNotFoundError(user_id)
    
    return user

# ❌ DON'T: Bare except, generic errors
def get_user(user_id):
    try:
        return user_repository.find_by_id(user_id)
    except:
        return None

Pythonic Patterns

python
# ✅ DO: List comprehensions, context managers, pythonic idioms
from contextlib import contextmanager
from pathlib import Path

def get_active_users(users: List[User]) -> List[User]:
    return [u for u in users if u.is_active]

@contextmanager
def open_database():
    """Context manager for database connection."""
    conn = create_connection()
    try:
        yield conn
    finally:
        conn.close()

def read_config(path: Path) -> dict:
    """Read config file."""
    with path.open() as f:
        return json.load(f)

# ❌ DON'T: Non-pythonic loops, manual resource management
def get_active_users(users):
    result = []
    for u in users:
        if u.is_active:
            result.append(u)
    return result

def read_config(path):
    f = open(path)
    data = json.load(f)
    f.close()
    return data

Dataclasses & Pydantic

python
# ✅ DO: Use dataclasses or pydantic for data structures
from dataclasses import dataclass
from datetime import datetime
from pydantic import BaseModel, EmailStr, validator

@dataclass
class User:
    id: str
    email: str
    created_at: datetime
    is_active: bool = True

# For validation, use Pydantic
class UserCreate(BaseModel):
    email: EmailStr
    password: str
    name: str
    
    @validator('password')
    def password_strength(cls, v):
        if len(v) < 8:
            raise ValueError('Password must be at least 8 characters')
        return v

# ❌ DON'T: Plain classes with manual __init__
class User:
    def __init__(self, id, email, created_at, is_active=True):
        self.id = id
        self.email = email
        self.created_at = created_at
        self.is_active = is_active

Async/Await

python
# ✅ DO: Proper async patterns
import asyncio
from typing import List

async def fetch_user(user_id: str) -> User:
    """Async fetch user."""
    async with httpx.AsyncClient() as client:
        response = await client.get(f"/users/{user_id}")
        response.raise_for_status()
        return User(**response.json())

async def fetch_multiple_users(user_ids: List[str]) -> List[User]:
    """Fetch multiple users concurrently."""
    tasks = [fetch_user(uid) for uid in user_ids]
    return await asyncio.gather(*tasks)

# ❌ DON'T: Blocking I/O in async functions
async def fetch_user(user_id: str) -> User:
    # BAD: Uses blocking requests library
    response = requests.get(f"/users/{user_id}")
    return User(**response.json())

Common Anti-Patterns

❌ Mutable Default Arguments

python
# Bad: Mutable default
def add_item(item, items=[]):
    items.append(item)
    return items

# Good: Use None
def add_item(item, items: Optional[List] = None) -> List:
    if items is None:
        items = []
    items.append(item)
    return items

❌ Not Using with for Resources

python
# Bad: Manual cleanup
file = open('data.txt')
data = file.read()
file.close()

# Good: Context manager
with open('data.txt') as file:
    data = file.read()

❌ Using from module import *

python
# Bad: Pollutes namespace
from users import *

# Good: Explicit imports
from users import User, UserService, get_user

Review Checklist

  • PEP 8 compliant (use black/ruff)
  • Type hints on all functions
  • Docstrings on public functions (Google or NumPy style)
  • No bare except: clauses
  • Context managers for resources
  • List/dict comprehensions where appropriate
  • F-strings for formatting (not %)
  • pathlib.Path instead of os.path
  • logging instead of print
  • mypy passes with no errors

Integration with Code Generator

When Code Generator requests Python implementation:

  1. Enforce type hints - require full typing
  2. Recommend libraries - pydantic, fastapi, sqlalchemy
  3. Pythonic patterns - comprehensions, context managers
  4. Error handling - custom exceptions
  5. Testing - pytest fixtures and parametrize
  6. Documentation - docstrings with examples

Evidence Format

markdown
### Python Expert Review

**PEP 8 Compliance**: ✅ Passes black/ruff
**Type Hints**: ✅ 100% coverage, mypy clean
**Pythonic Patterns**: ✅ Comprehensions, context managers
**Error Handling**: ✅ Custom exception hierarchy
**Documentation**: ✅ All public APIs documented

**Issues**: None
**Recommendations**:
- Consider using pydantic for data validation
- Add property-based tests with hypothesis