Читаешь ли документацию для написания кода
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Роль документации в разработке
Да, я активно читаю документацию
Да, чтение документации — это критически важная часть моей разработки. Я убедился, что пропуск документации приводит к багам, неправильному использованию API и потере времени.
Когда я читаю документацию
1. Перед началом проекта
Когда выбираю технологический стек, первое, что делаю — изучаю официальную документацию:
# Например, выбираю между asyncio, trio, anyio
# Читаю:
# - asyncio (https://docs.python.org/3/library/asyncio.html)
# - trio (https://trio.readthedocs.io/)
# - anyio (https://anyio.readthedocs.io/)
# Вывод: anyio имеет лучший cancellation API
import anyio
async def main():
with anyio.CancelScope() as cancel_scope:
if some_condition:
cancel_scope.cancel() # Очень ясный API
2. При интеграции новой библиотеки
Никогда не копирую код с StackOverflow слепо. Всегда сначала читаю oficialную документацию:
# НЕПРАВИЛЬНО: скопировал с SO
from sqlalchemy import create_engine
engine = create_engine("sqlite:///db.sqlite")
session = Session(engine)
user = session.query(User).first() # Deprecated pattern!
# ПРАВИЛЬНО: прочитал SQLAlchemy 2.0 docs
from sqlalchemy import create_engine, select
from sqlalchemy.orm import Session
engine = create_engine("sqlite:///db.sqlite")
with Session(engine) as session:
stmt = select(User).limit(1)
user = session.execute(stmt).scalar() # Новый pattern
3. Перед использованием сложных фич
Документация помогает избежать подводных камней:
# Без документации мог бы упустить важность связи между
# timeout и cancel scope в asyncio
import asyncio
async def fetch_data_safely():
# НЕПРАВИЛЬНО: timeout не отменяет задачу, только ждёт
try:
result = await asyncio.wait_for(
slow_operation(),
timeout=5
)
except asyncio.TimeoutError:
# slow_operation всё ещё работает в фоне!
pass
# ПРАВИЛЬНО: использую cancel scope (trio) или task.cancel() (asyncio)
task = asyncio.create_task(slow_operation())
try:
result = await asyncio.wait_for(task, timeout=5)
except asyncio.TimeoutError:
task.cancel() # Явная отмена
try:
await task
except asyncio.CancelledError:
pass
Типы документации, которые я читаю
1. Официальная документация (первый приоритет)
✅ https://docs.python.org/
✅ https://fastapi.tiangolo.com/
✅ https://sqlalchemy.org/
✅ https://pydantic-docs.helpmanual.io/
✅ https://asyncio.readthedocs.io/
2. RFC и PEP (для понимания философии)
# PEP 8 — Style Guide
# PEP 20 — Zen of Python
# PEP 484 — Type Hints
# PEP 492 — Coroutines
# PEP 673 — TypeVar with bound
# Пример: после чтения PEP 492, понимаю различие:
async def coro(): # Это синтаксис async, определён в PEP 492
await other_coro()
def gen():
yield 1 # Это generator, работает иначе
3. Changelog и Migration guides
Критично при обновлениях версий:
# FastAPI 0.100.0 добавил новый параметр
# Если не читал changelog, мог бы использовать deprecated API
# ДО (FastAPI < 0.100)
from fastapi import APIRouter
router = APIRouter()
# ПОСЛЕ (читал changelog)
router = APIRouter(prefix="/api/v1")
# Теперь можно убрать prefix из всех routes
Как я организую изучение документации
Шаг 1: Overview
Прочитаю введение и основные концепции:
# FastAPI Docs
1. Introduction ← начинаю отсюда
2. Installation
3. Quickstart
4. User Guide (skip пока)
Шаг 2: Relevant Section
Нахожу раздел, относящийся к моей задаче:
# Ищу решение для async validation
- Request Body → Pydantic → Validators
Шаг 3: Example Code
Запускаю примеры локально, экспериментирую:
# Из документации FastAPI
from pydantic import BaseModel, field_validator
class Item(BaseModel):
name: str
price: float
@field_validator('price')
@classmethod
def price_must_be_positive(cls, v):
if v <= 0:
raise ValueError('Price must be positive')
return v
# Экспериментирую
item = Item(name="Book", price=-10) # Проверяю, выбросится ли ошибка
Шаг 4: Edge Cases
Читаю про ограничения и подводные камни:
# Из документации Pydantic
# "Field validators run BEFORE type coercion"
# Это важно для правильного порядка проверок
from pydantic import BaseModel, field_validator
class Model(BaseModel):
value: int
@field_validator('value', mode='before')
@classmethod
def validate_before_coerce(cls, v):
# v здесь может быть строка "123", не число
if isinstance(v, str):
return int(v)
return v
Документация vs StackOverflow
| Источник | Плюсы | Минусы |
|---|---|---|
| Документация | Актуальная, полная, правильная | Может быть скучной |
| StackOverflow | Решения реальных проблем | Часто устаревает, может быть неправильной |
| Блоги | Примеры use-cases | Субъективно, не авторитетно |
Мой подход:
Документация → StackOverflow → Исходный код (если документ молчит)
Примеры, где документация спасла меня
1. Asyncio и race conditions
Документация asyncio объясняет, почему asyncio.gather() с return_exceptions=True критична:
# БЕЗ знания документации, мог бы упустить одну из задач
tasks = [fetch_data(i) for i in range(10)]
# НЕПРАВИЛЬНО: одна ошибка — всё падает
results = await asyncio.gather(*tasks) # ❌ Если task[5] упадёт, остальные отменяются
# ПРАВИЛЬНО: (после чтения docs)
results = await asyncio.gather(*tasks, return_exceptions=True) # ✅ Все выполняются
2. SQLAlchemy Session scope
Документация объясняет, почему нужна session scope в многопоточности:
# Без документации, мог бы создавать session глобально
# Это привело бы к race conditions
from sqlalchemy.orm import sessionmaker, Session
from contextvars import ContextVar
# ПРАВИЛЬНО: после чтения docs
session_context: ContextVar[Session] = ContextVar('session')
def get_session() -> Session:
try:
return session_context.get()
except LookupError:
session = SessionLocal()
session_context.set(session)
return session
3. Pydantic model_dump vs dict
Документация объясняет разницу:
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
user = User(id=1, name="John")
# СТАРЫЙ способ (deprecated)
user.dict() # ❌
# НОВЫЙ способ (из docs v2)
user.model_dump() # ✅ Правильно для Pydantic v2
Документация в команде
Когда я веду код review, проверяю:
# Вопрос: почему используется именно этот параметр?
from asyncio import gather
results = await gather(
*tasks,
return_exceptions=True # ← Может быть улучшено?
)
# Проверяю документацию gather():
# "If return_exceptions is False (default), the first raised exception is immediately
# propagated to the task that awaits on gather()."
# Комментарий в code review:
# "Почему return_exceptions=True? Если мы хотим отказаться от одной из задач,
# может быть, лучше использовать asyncio.TaskGroup для явной отмены?"
Мой совет молодым разработчикам
"""
Ник(читаю ли документацию):
- ПЕРВЫЙ месяц: документация 80%, StackOverflow 20%
- ПОСЛЕ 6 месяцев: документация 60%, StackOverflow 40%
- ПОСЛЕ 2 лет: документация 50%, StackOverflow 30%, исходный код 20%
Ключное правило: никогда не доверяй примерам из StackOverflow
без проверки в официальной документации.
"""
Инструменты для чтения документации
# Просмотр docs локально
pip install sphinx-doc
# Поиск в документации
grep -r "timeout" /path/to/docs/
# Запуск примеров из документации
jupyter notebook # для экспериментов
Итог
Я читаю документацию потому что:
- Экономия времени — один раз прочитал правильно, потом не ищу баги
- Избегаю ошибок — документация показывает подводные камни
- Понимаю философию — зачем именно так сделано, не просто копирую
- Уважение к авторам — они потратили время, я уважаю их работу
- Модель для команды — если я читаю docs, моя команда тоже будет
Программист без документации — как пилот без карты. Вроде можешь летать, но в 10 раз больше вероятность крушения.