Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
affaan-m avatar

Python Patterns

  • 7.4k installs
  • 234k repo stars
  • Updated July 27, 2026
  • affaan-m/everything-claude-code

Python design patterns skill covering protocols, dataclasses, context managers, generators, decorators, async/await, type hints, dependency injection, package organization, and functional programming for Pythonic code

About

This skill provides Python-specific design patterns and best practices for developers writing Pythonic code. It covers protocols for duck typing with type hints, dataclasses for DTOs, context managers for resource handling, generators for memory efficiency, decorators for cross-cutting concerns, async/await patterns for concurrent I/O, advanced type hints including generics and ParamSpec, dependency injection, package organization, custom exceptions, property decorators, and functional programming utilities. Developers invoke this when structuring Python projects, designing APIs, implementing async systems, or refactoring codebases to use idiomatic Python patterns. The skill extends common design principles with Python-specific idioms like frozen dataclasses, contextlib decorators, and asyncio.gather for concurrent execution.

  • Protocols enable structural subtyping without inheritance, providing type-safe duck typing for flexible interfaces
  • Context managers handle resources with __enter__/__exit__ or @contextmanager decorator for automatic cleanup
  • Generators and generator expressions provide lazy evaluation for memory-efficient processing of large datasets
  • Advanced type hints include Generic[T], ParamSpec, and union types with pattern matching for type-safe APIs
  • Async/await patterns with asyncio.gather enable concurrent I/O operations and async context managers

Python Patterns by the numbers

  • 7,425 all-time installs (skills.sh)
  • +341 installs in the week ending Jul 28, 2026 (Skillselion tracking)
  • Ranked #6 of 311 Python skills by installs in the Skillselion catalog
  • Security screen: LOW risk (skills.sh audit)
  • Data as of Jul 28, 2026 (Skillselion catalog sync)
At a glance

python-patterns capabilities & compatibility

Capabilities
protocol based duck typing · dataclass dtos · context managers · generators · decorators · async await · advanced type hints · dependency injection
Use cases
api development · refactoring
Platforms
macOS · Windows · Linux
IDEs
vscode · cursor ide · pycharm · intellij
Runs
Runs locally
Pricing
Free
npx skills add https://github.com/affaan-m/everything-claude-code --skill python-patterns

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs7.4k
repo stars234k
Security audit3 / 3 scanners passed
Last updatedJuly 27, 2026
Repositoryaffaan-m/everything-claude-code

What it does

Apply Python-specific design patterns and idioms when building Python backends, APIs, or libraries.

Who is it for?

Python backend development, API design, library construction, async systems, refactoring legacy Python code to idiomatic patterns

Skip if: Non-Python languages, frontend-specific patterns, database schema design, deployment configuration

When should I use this skill?

Structuring Python projects, designing APIs or packages, implementing async/concurrent systems, refactoring to Pythonic patterns, writing type-safe Python code

What you get

Developers write Pythonic code using protocols for duck typing, dataclasses for DTOs, context managers for resources, generators for lazy evaluation, async/await for concurrency, and advanced type hints for type safety

  • Type-safe Python code using protocols and generics
  • memory-efficient generators
  • async/await concurrent operations

By the numbers

  • 5 major pattern categories: protocols, dataclasses, context managers, generators, async/await
  • Python 3.10+ required for union types and match statements
  • Python 3.11+ required for exception groups

Files

SKILL.mdMarkdownGitHub ↗

Python Patterns

This skill provides comprehensive Python patterns extending common design principles with Python-specific idioms.

Protocol (Duck Typing)

Use Protocol for structural subtyping (duck typing with type hints):

from typing import Protocol

class Repository(Protocol):
    def find_by_id(self, id: str) -> dict | None: ...
    def save(self, entity: dict) -> dict: ...

# Any class with these methods satisfies the protocol
class UserRepository:
    def find_by_id(self, id: str) -> dict | None:
        # implementation
        pass

    def save(self, entity: dict) -> dict:
        # implementation
        pass

def process_entity(repo: Repository, id: str) -> None:
    entity = repo.find_by_id(id)
    # ... process

Benefits:

  • Type safety without inheritance
  • Flexible, loosely coupled code
  • Easy testing and mocking

Dataclasses as DTOs

Use dataclass for data transfer objects and value objects:

from dataclasses import dataclass, field
from typing import Optional

@dataclass
class CreateUserRequest:
    name: str
    email: str
    age: Optional[int] = None
    tags: list[str] = field(default_factory=list)

@dataclass(frozen=True)
class User:
    """Immutable user entity"""
    id: str
    name: str
    email: str

Features:

  • Auto-generated __init__, __repr__, __eq__
  • frozen=True for immutability
  • field() for complex defaults
  • Type hints for validation

Context Managers

Use context managers (with statement) for resource management:

from contextlib import contextmanager
from typing import Generator

@contextmanager
def database_transaction(db) -> Generator[None, None, None]:
    """Context manager for database transactions"""
    try:
        yield
        db.commit()
    except Exception:
        db.rollback()
        raise

# Usage
with database_transaction(db):
    db.execute("INSERT INTO users ...")

Class-based context manager:

class FileProcessor:
    def __init__(self, filename: str):
        self.filename = filename
        self.file = None

    def __enter__(self):
        self.file = open(self.filename, 'r')
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        if self.file:
            self.file.close()
        return False  # Don't suppress exceptions

Generators

Use generators for lazy evaluation and memory-efficient iteration:

def read_large_file(filename: str):
    """Generator for reading large files line by line"""
    with open(filename, 'r') as f:
        for line in f:
            yield line.strip()

# Memory-efficient processing
for line in read_large_file('huge.txt'):
    process(line)

Generator expressions:

# Instead of list comprehension
squares = (x**2 for x in range(1000000))  # Lazy evaluation

# Pipeline pattern
numbers = (x for x in range(100))
evens = (x for x in numbers if x % 2 == 0)
squares = (x**2 for x in evens)

Decorators

Function Decorators

from functools import wraps
import time

def timing(func):
    """Decorator to measure execution time"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} took {end - start:.2f}s")
        return result
    return wrapper

@timing
def slow_function():
    time.sleep(1)

Class Decorators

def singleton(cls):
    """Decorator to make a class a singleton"""
    instances = {}

    @wraps(cls)
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]

    return get_instance

@singleton
class Config:
    pass

Async/Await

Async Functions

import asyncio
from typing import List

async def fetch_user(user_id: str) -> dict:
    """Async function for I/O-bound operations"""
    await asyncio.sleep(0.1)  # Simulate network call
    return {"id": user_id, "name": "Alice"}

async def fetch_all_users(user_ids: List[str]) -> List[dict]:
    """Concurrent execution with asyncio.gather"""
    tasks = [fetch_user(uid) for uid in user_ids]
    return await asyncio.gather(*tasks)

# Run async code
asyncio.run(fetch_all_users(["1", "2", "3"]))

Async Context Managers

class AsyncDatabase:
    async def __aenter__(self):
        await self.connect()
        return self

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.disconnect()

async with AsyncDatabase() as db:
    await db.query("SELECT * FROM users")

Type Hints

Advanced Type Hints

from typing import TypeVar, Generic, Callable, ParamSpec, Concatenate

T = TypeVar('T')
P = ParamSpec('P')

class Repository(Generic[T]):
    """Generic repository pattern"""
    def __init__(self, entity_type: type[T]):
        self.entity_type = entity_type

    def find_by_id(self, id: str) -> T | None:
        # implementation
        pass

# Type-safe decorator
def log_call(func: Callable[P, T]) -> Callable[P, T]:
    @wraps(func)
    def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
        print(f"Calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

Union Types (Python 3.10+)

def process(value: str | int | None) -> str:
    match value:
        case str():
            return value.upper()
        case int():
            return str(value)
        case None:
            return "empty"

Dependency Injection

Constructor Injection

class UserService:
    def __init__(
        self,
        repository: Repository,
        logger: Logger,
        cache: Cache | None = None
    ):
        self.repository = repository
        self.logger = logger
        self.cache = cache

    def get_user(self, user_id: str) -> User | None:
        if self.cache:
            cached = self.cache.get(user_id)
            if cached:
                return cached

        user = self.repository.find_by_id(user_id)
        if user and self.cache:
            self.cache.set(user_id, user)

        return user

Package Organization

Project Structure

project/
├── src/
│   └── mypackage/
│       ├── __init__.py
│       ├── domain/          # Business logic
│       │   ├── __init__.py
│       │   └── models.py
│       ├── services/        # Application services
│       │   ├── __init__.py
│       │   └── user_service.py
│       └── infrastructure/  # External dependencies
│           ├── __init__.py
│           └── database.py
├── tests/
│   ├── unit/
│   └── integration/
├── pyproject.toml
└── README.md

Module Exports

# __init__.py
from .models import User, Product
from .services import UserService

__all__ = ['User', 'Product', 'UserService']

Error Handling

Custom Exceptions

class DomainError(Exception):
    """Base exception for domain errors"""
    pass

class UserNotFoundError(DomainError):
    """Raised when user is not found"""
    def __init__(self, user_id: str):
        self.user_id = user_id
        super().__init__(f"User {user_id} not found")

class ValidationError(DomainError):
    """Raised when validation fails"""
    def __init__(self, field: str, message: str):
        self.field = field
        self.message = message
        super().__init__(f"{field}: {message}")

Exception Groups (Python 3.11+)

try:
    # Multiple operations
    pass
except* ValueError as eg:
    # Handle all ValueError instances
    for exc in eg.exceptions:
        print(f"ValueError: {exc}")
except* TypeError as eg:
    # Handle all TypeError instances
    for exc in eg.exceptions:
        print(f"TypeError: {exc}")

Property Decorators

class User:
    def __init__(self, name: str):
        self._name = name
        self._email = None

    @property
    def name(self) -> str:
        """Read-only property"""
        return self._name

    @property
    def email(self) -> str | None:
        return self._email

    @email.setter
    def email(self, value: str) -> None:
        if '@' not in value:
            raise ValueError("Invalid email")
        self._email = value

Functional Programming

Higher-Order Functions

from functools import reduce
from typing import Callable, TypeVar

T = TypeVar('T')
U = TypeVar('U')

def pipe(*functions: Callable) -> Callable:
    """Compose functions left to right"""
    def inner(arg):
        return reduce(lambda x, f: f(x), functions, arg)
    return inner

# Usage
process = pipe(
    str.strip,
    str.lower,
    lambda s: s.replace(' ', '_')
)
result = process("  Hello World  ")  # "hello_world"

When to Use This Skill

  • Designing Python APIs and packages
  • Implementing async/concurrent systems
  • Structuring Python projects
  • Writing Pythonic code
  • Refactoring Python codebases
  • Type-safe Python development

Related skills

Forks & variants (1)

Python Patterns has 1 known copy in the catalog totaling 1.5k installs. They canonicalize to this original listing.

How it compares

Baseline Python idioms and PEP 8; pair with django-patterns or framework skills for web stack specifics.

FAQ

When should I use Protocol vs ABC for interfaces?

Use Protocol for structural subtyping without inheritance - any class with matching methods satisfies the protocol. Use ABC when you need explicit inheritance and shared implementation via abstract base classes.

How do I make a dataclass immutable?

Use @dataclass(frozen=True) decorator to create immutable dataclasses where all fields are read-only after initialization, suitable for value objects and entities.

What's the difference between generators and list comprehensions?

Generators use parentheses and provide lazy evaluation - values computed on-demand - making them memory-efficient for large datasets. List comprehensions use brackets and create entire lists in memory upfront.

Is Python Patterns safe to install?

skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.

Pythonbackendintegrations

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.