Technical
Python Patterns I Discovered Writing Daily Code in 2025
Writing Python every day for a full year will show you which patterns are worth keeping. Some patterns I learned early got refined. Some new patterns emerged from the repetition. Here are the Python patterns that earned their spot in my default toolbox this year.
Pattern 1: Dataclasses for Config, Pydantic for Input
Two types of data, two tools. Internal config is a dataclass. External input is a Pydantic model. The line between them clarifies which data needs validation and which is already trusted.
from dataclasses import dataclass
from pydantic import BaseModel
@dataclass
class AppConfig:
database_url: str
debug: bool = False
class UserCreate(BaseModel):
email: str
name: str | None = NonePattern 2: Context Managers for Resources
Any resource with setup and teardown goes through a with block. Database connections, HTTP sessions, file handles. This is old advice but it still matters. Never manually close what a context manager can close for you.
Pattern 3: Pathlib Over os.path
I deleted every os.path.join call this year. Path objects read better, handle edge cases better, and integrate with modern APIs. No more string concatenation for file paths.
from pathlib import Path
config_file = Path(__file__).parent / 'config.json'Pattern 4: Type Hints for Self-Documentation
Every function I write has type hints. Not for the type checker (though ruff catches many issues). For the human reading it six months later. Type hints are cheap documentation that never lies.
Pattern 5: f-Strings for Everything
No .format(). No % formatting. Just f-strings. They are faster, they read better, they handle most cases without gymnastics.
Pattern 6: Match Statements for Dispatch
Python 3.10 match statements replaced several of my long if-elif chains this year. For simple value dispatch they are cleaner than the alternatives.
match event.type:
case 'post.created':
handle_post_created(event)
case 'user.registered':
handle_user_registered(event)
case _:
log_unknown_event(event)Pattern 7: Walrus for Scoped Assignments
The walrus operator (:=) is not for every case but in list comprehensions with computed filters it removes duplicate work. Use sparingly, read it out loud first.
The Pattern Behind the Patterns
Every one of these patterns does the same meta-thing: it makes code easier to read six months later. That is the only metric that matters for patterns. If it does not improve future-reading, skip it.
For the full modern Python guide, see Python 3.12 release notes and the patterns that came with the recent versions.
RELATED READING
The Consulting Shift I Am Making In Year Two
After a year of writing and building, my consulting practice is changing shape. Shorter engagements. Sharper outcomes.
ReadThe Frontend Shift: Shipping Less JavaScript In Year Two
A year ago I reached for Next.js for everything. This year I often reach for nothing.
ReadThe Serverless Lesson I Would Write On A Sticky Note
After a year of shipping serverless projects, one rule explains most of the wins and all of the losses.
Read