| name | python-patterns |
| description | Pythonic idioms, PEP 8 standards, type hints, and best practices for building robust, efficient, and maintainable Python applications. |
| origin | ECC |
| group | domain |
| triggers | ["Python код","питоновский стиль","type hints","pyproject.toml"] |
| output | idiomatic Python code with type hints, proper error handling, and best practices |
| calls | [] |
Python Development Patterns
Idiomatic Python patterns and best practices for building robust, efficient, and maintainable applications.
When to Activate
- Writing new Python code
- Reviewing Python code
- Refactoring existing Python code
- Designing Python packages/modules
Core Principles
1. Readability Counts
def get_active_users(users: list[User]) -> list[User]:
return [user for user in users if user.is_active]
def get_active_users(u):
return [x for x in u if x.a]
2. Explicit is Better Than Implicit
Avoid magic; be clear about what your code does.
3. EAFP — Easier to Ask Forgiveness Than Permission
def get_value(dictionary: dict, key: str) -> Any:
try:
return dictionary[key]
except KeyError:
return default_value
def get_value(dictionary: dict, key: str) -> Any:
if key in dictionary:
return dictionary[key]
return default_value
Type Hints
Modern Type Hints (Python 3.9+)
def process_items(items: list[str]) -> dict[str, int]:
return {item: len(item) for item in items}
from typing import TypeVar
T = TypeVar('T')
def first(items: list[T]) -> T | None:
return items[0] if items else None
Protocol-Based Duck Typing
from typing import Protocol
class Renderable(Protocol):
def render(self) -> str: ...
def render_all(items: list[Renderable]) -> str:
return "\n".join(item.render() for item in items)
Error Handling
Specific Exception Handling
def load_config(path: str) -> Config:
try:
with open(path) as f:
return Config.from_json(f.read())
except FileNotFoundError as e:
raise ConfigError(f"Config file not found: {path}") from e
except json.JSONDecodeError as e:
raise ConfigError(f"Invalid JSON in config: {path}") from e
try:
...
except:
return None
Custom Exception Hierarchy
class AppError(Exception): pass
class ValidationError(AppError): pass
class NotFoundError(AppError): pass
Context Managers
with open(path, 'r') as f:
return f.read()
from contextlib import contextmanager
@contextmanager
def timer(name: str):
start = time.perf_counter()
yield
print(f"{name} took {time.perf_counter() - start:.4f}s")
Data Classes
from dataclasses import dataclass, field
from datetime import datetime
@dataclass
class User:
id: str
name: str
email: str
created_at: datetime = field(default_factory=datetime.now)
is_active: bool = True
def __post_init__(self):
if "@" not in self.email:
raise ValueError(f"Invalid email: {self.email}")
Generators for Large Data
def read_large_file(path: str) -> Iterator[str]:
with open(path) as f:
for line in f:
yield line.strip()
total = sum(x * x for x in range(1_000_000))
Concurrency
import concurrent.futures
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
results = list(executor.map(fetch_url, urls))
with concurrent.futures.ProcessPoolExecutor() as executor:
results = list(executor.map(heavy_compute, datasets))
async def fetch_all(urls: list[str]) -> list[str]:
tasks = [fetch_async(url) for url in urls]
return await asyncio.gather(*tasks, return_exceptions=True)
Memory Optimization
class Point:
__slots__ = ['x', 'y']
def __init__(self, x: float, y: float):
self.x, self.y = x, y
result = "".join(str(item) for item in items)
Tooling
black .
isort .
ruff check .
mypy .
pytest
bandit -r .
pyproject.toml
[tool.black]
line-length = 88
target-version = ['py39']
[tool.ruff]
line-length = 88
select = ["E", "F", "I", "N", "W"]
[tool.mypy]
python_version = "3.9"
disallow_untyped_defs = true
warn_return_any = true
Anti-Patterns
def append_to(item, items=[]):
items.append(item)
def append_to(item, items=None):
if items is None: items = []
items.append(item)
if type(obj) == list: ...
if isinstance(obj, list): ...
if value == None: ...
if value is None: ...
from os.path import *
from os.path import join, exists
Quick Reference
| Idiom | Description |
|---|
| EAFP | Try first, handle exceptions |
| Context managers | with for all resources |
| List comprehensions | Simple transformations |
| Generators | Lazy evaluation, large datasets |
| Type hints | Annotate all function signatures |
| Dataclasses | Data containers with auto methods |
__slots__ | Memory optimization |
| f-strings | String formatting (3.6+) |
pathlib.Path | Path operations (3.4+) |
enumerate | Index-element pairs in loops |